1
|
|
|
# Copyright Pincer 2021-Present |
|
|
|
|
2
|
|
|
# Full MIT License can be found in `LICENSE` at the project root. |
3
|
|
|
|
4
|
|
|
from __future__ import annotations |
5
|
|
|
|
6
|
|
|
from dataclasses import dataclass, field |
7
|
|
|
from datetime import datetime |
8
|
|
|
from enum import IntEnum |
9
|
|
|
from typing import overload, TYPE_CHECKING |
10
|
|
|
|
11
|
|
|
from aiohttp import FormData |
|
|
|
|
12
|
|
|
|
13
|
|
|
from .channel import Channel, Thread |
14
|
|
|
from .scheduled_events import ScheduledEvent, GuildScheduledEventUser |
15
|
|
|
from ..message.emoji import Emoji |
16
|
|
|
from ..message.file import File |
17
|
|
|
from ...exceptions import UnavailableGuildError |
18
|
|
|
from ...utils import remove_none |
19
|
|
|
from ...utils.api_data import APIDataGen |
20
|
|
|
from ...utils.api_object import APIObject |
21
|
|
|
from ...utils.types import MISSING |
22
|
|
|
|
23
|
|
|
from .audit_log import AuditLog |
24
|
|
|
from .ban import Ban |
25
|
|
|
from .member import GuildMember |
26
|
|
|
from .invite import Invite |
27
|
|
|
from .role import Role |
28
|
|
|
from .template import GuildTemplate |
29
|
|
|
from .welcome_screen import WelcomeScreen |
30
|
|
|
from .widget import GuildWidget |
31
|
|
|
from .webhook import Webhook |
32
|
|
|
from ..user.integration import Integration |
33
|
|
|
from ..voice.region import VoiceRegion |
34
|
|
|
from ..message.sticker import Sticker |
35
|
|
|
|
36
|
|
|
if TYPE_CHECKING: |
37
|
|
|
from typing import Any, Dict, List, Optional, Tuple, Union, Generator |
38
|
|
|
|
39
|
|
|
from ..events.presence import PresenceUpdateEvent |
40
|
|
|
from .channel import ChannelType |
41
|
|
|
from .features import GuildFeature |
42
|
|
|
from .overwrite import Overwrite |
43
|
|
|
from .stage import StageInstance |
44
|
|
|
from .welcome_screen import WelcomeScreenChannel |
45
|
|
|
from ..user.user import User |
46
|
|
|
from ..user.voice_state import VoiceState |
47
|
|
|
from ...client import Client |
48
|
|
|
from ...utils.timestamp import Timestamp |
49
|
|
|
from ...utils.types import APINullable, JSONSerializable |
50
|
|
|
from ...utils.snowflake import Snowflake |
51
|
|
|
|
52
|
|
|
|
53
|
|
|
class PremiumTier(IntEnum): |
54
|
|
|
"""Represents the boost tier of a guild. |
55
|
|
|
Attributes |
56
|
|
|
---------- |
57
|
|
|
NONE: |
58
|
|
|
Guild has not unlocked any Server Boost perks. |
59
|
|
|
TIER_1: |
60
|
|
|
Guild has unlocked Server Boost level 1 perks. |
61
|
|
|
TIER_2: |
62
|
|
|
Guild has unlocked Server Boost level 2 perks. |
63
|
|
|
TIER_3: |
64
|
|
|
Guild has unlocked Server Boost level 3 perks. |
65
|
|
|
""" |
66
|
|
|
|
67
|
|
|
NONE = 0 |
68
|
|
|
TIER_1 = 1 |
69
|
|
|
TIER_2 = 2 |
70
|
|
|
TIER_3 = 3 |
71
|
|
|
|
72
|
|
|
|
73
|
|
|
class GuildNSFWLevel(IntEnum): |
74
|
|
|
"""Represents the NSFW level of a guild. |
75
|
|
|
Attributes |
76
|
|
|
---------- |
77
|
|
|
DEFAULT: |
78
|
|
|
Default NSFW level. |
79
|
|
|
EXPLICIT: |
80
|
|
|
Explicit NSFW level. |
81
|
|
|
SAFE: |
82
|
|
|
SAFE NSFW level. |
83
|
|
|
AGE_RESTRICTED: |
84
|
|
|
Age restricted NSFW level. |
85
|
|
|
""" |
86
|
|
|
|
87
|
|
|
DEFAULT = 0 |
88
|
|
|
EXPLICIT = 1 |
89
|
|
|
SAFE = 2 |
90
|
|
|
AGE_RESTRICTED = 3 |
91
|
|
|
|
92
|
|
|
|
93
|
|
|
class ExplicitContentFilterLevel(IntEnum): |
94
|
|
|
"""Represents the filter content level of a guild. |
95
|
|
|
Attributes |
96
|
|
|
---------- |
97
|
|
|
DISABLED: |
98
|
|
|
Media content will not be scanned. |
99
|
|
|
MEMBERS_WITHOUT_ROLES: |
100
|
|
|
Media content sent by members without roles will be scanned. |
101
|
|
|
ALL_MEMBERS: |
102
|
|
|
Media content sent by all members will be scanned. |
103
|
|
|
""" |
104
|
|
|
|
105
|
|
|
DISABLED = 0 |
106
|
|
|
MEMBERS_WITHOUT_ROLES = 1 |
107
|
|
|
ALL_MEMBERS = 2 |
108
|
|
|
|
109
|
|
|
|
110
|
|
|
class MFALevel(IntEnum): |
111
|
|
|
"""Represents the multi-factor authentication level of a guild. |
112
|
|
|
Attributes |
113
|
|
|
---------- |
114
|
|
|
NONE: |
115
|
|
|
Guild has no MFA/2FA requirement for moderation actions. |
116
|
|
|
ELEVATED: |
117
|
|
|
Guild has a 2FA requirement for moderation actions |
118
|
|
|
""" |
119
|
|
|
|
120
|
|
|
NONE = 0 |
121
|
|
|
ELEVATED = 1 |
122
|
|
|
|
123
|
|
|
|
124
|
|
|
class VerificationLevel(IntEnum): |
125
|
|
|
"""Represents the verification level of a guild. |
126
|
|
|
Attributes |
127
|
|
|
---------- |
128
|
|
|
NONE: |
129
|
|
|
Unrestricted. |
130
|
|
|
LOW: |
131
|
|
|
Must have verified email on account. |
132
|
|
|
MEDIUM: |
133
|
|
|
Must be registered on Discord for longer than 5 minutes. |
134
|
|
|
HIGH: |
135
|
|
|
Must be a member of the server for longer than 10 minutes. |
136
|
|
|
VERY_HIGH: |
137
|
|
|
Must have a verified phone number. |
138
|
|
|
""" |
139
|
|
|
|
140
|
|
|
NONE = 0 |
141
|
|
|
LOW = 1 |
142
|
|
|
MEDIUM = 2 |
143
|
|
|
HIGH = 3 |
144
|
|
|
VERY_HIGH = 4 |
145
|
|
|
|
146
|
|
|
|
147
|
|
|
class DefaultMessageNotificationLevel(IntEnum): |
148
|
|
|
"""Represents the default message notification level of a guild. |
149
|
|
|
Attributes |
150
|
|
|
---------- |
151
|
|
|
ALL_MESSAGES: |
152
|
|
|
Members will receive notifications for all messages by default. |
153
|
|
|
ONLY_MENTIONS: |
154
|
|
|
Members will receive notifications only for messages that @mention them by default. |
155
|
|
|
""" |
156
|
|
|
|
157
|
|
|
# noqa: E501 |
158
|
|
|
ALL_MESSAGES = 0 |
159
|
|
|
ONLY_MENTIONS = 1 |
160
|
|
|
|
161
|
|
|
|
162
|
|
|
class SystemChannelFlags(IntEnum): |
163
|
|
|
"""Represents the system channel flags of a guild. |
164
|
|
|
Attributes |
165
|
|
|
---------- |
166
|
|
|
SUPPRESS_JOIN_NOTIFICATIONS: |
167
|
|
|
Suppress member join notifications. |
168
|
|
|
SUPPRESS_PREMIUM_SUBSCRIPTIONS: |
169
|
|
|
Suppress server boost notifications. |
170
|
|
|
SUPPRESS_GUILD_REMINDER_NOTIFICATIONS: |
171
|
|
|
Suppress server setup tips. |
172
|
|
|
SUPPRESS_JOIN_NOTIFICATION_REPLIES: |
173
|
|
|
Hide member join sticker reply buttons |
174
|
|
|
""" |
175
|
|
|
|
176
|
|
|
SUPPRESS_JOIN_NOTIFICATIONS = 1 << 0 |
177
|
|
|
SUPPRESS_PREMIUM_SUBSCRIPTIONS = 1 << 1 |
178
|
|
|
SUPPRESS_GUILD_REMINDER_NOTIFICATIONS = 1 << 2 |
179
|
|
|
SUPPRESS_JOIN_NOTIFICATION_REPLIES = 1 << 3 |
180
|
|
|
|
181
|
|
|
|
182
|
|
|
@dataclass(repr=False) |
183
|
|
|
class GuildPreview(APIObject): |
|
|
|
|
184
|
|
|
"""Represents a guild preview. |
185
|
|
|
Attributes |
186
|
|
|
---------- |
187
|
|
|
id: :class:`Snowflake` |
188
|
|
|
The guild ID. |
189
|
|
|
name: :class:`str` |
190
|
|
|
The guild name. |
191
|
|
|
icon: :class:`str` |
192
|
|
|
The guild icon hash. |
193
|
|
|
splash: :class:`str` |
194
|
|
|
The guild splash hash. |
195
|
|
|
discovery_splash: :class:`str` |
196
|
|
|
The guild discovery splash hash. |
197
|
|
|
emojis: :class:`List[Emoji]` |
198
|
|
|
The guild emojis. |
199
|
|
|
features: :class:`List[GuildFeature]` |
200
|
|
|
The guild features. |
201
|
|
|
approximate_member_count: :class:`int` |
202
|
|
|
The approximate member count. |
203
|
|
|
approximate_presence_count: :class:`int` |
204
|
|
|
The approximate number of online members in this guild |
205
|
|
|
description: :class:`str` |
206
|
|
|
The guild description. |
207
|
|
|
""" |
208
|
|
|
|
209
|
|
|
id: Snowflake |
210
|
|
|
name: str |
211
|
|
|
emojis: List[Emoji] |
212
|
|
|
features: List[GuildFeature] |
213
|
|
|
approximate_member_count: int |
214
|
|
|
approximate_presence_count: int |
215
|
|
|
|
216
|
|
|
icon: APINullable[str] = MISSING |
217
|
|
|
splash: APINullable[str] = MISSING |
218
|
|
|
discovery_splash: APINullable[str] = MISSING |
219
|
|
|
description: APINullable[str] = MISSING |
220
|
|
|
|
221
|
|
|
|
222
|
|
|
@dataclass(repr=False) |
223
|
|
|
class Guild(APIObject): |
|
|
|
|
224
|
|
|
"""Represents a Discord guild/server in which your client resides. |
225
|
|
|
Attributes |
226
|
|
|
---------- |
227
|
|
|
afk_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`] |
228
|
|
|
Id of afk channel |
229
|
|
|
afk_timeout: :class:`int` |
230
|
|
|
Afk timeout in seconds |
231
|
|
|
application_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`] |
232
|
|
|
Application id of the guild creator if it is bot-created |
233
|
|
|
banner: Optional[:class:`str`] |
234
|
|
|
Banner hash |
235
|
|
|
default_message_notifications: :class:`~pincer.objects.guild.guild.DefaultMessageNotificationLevel` |
|
|
|
|
236
|
|
|
Default message notifications level |
237
|
|
|
description: Optional[:class:`str`] |
238
|
|
|
The description of a Community guild |
239
|
|
|
discovery_splash: Optional[:class:`str`] |
240
|
|
|
Discovery splash hash; |
241
|
|
|
only present for guilds with the "DISCOVERABLE" feature |
242
|
|
|
emojis: List[:class:`~pincer.objects.message.emoji.Emoji`] |
243
|
|
|
Custom guild emojis |
244
|
|
|
explicit_content_filter: :class:`~pincer.objects.guild.guild.ExplicitContentFilterLevel` |
245
|
|
|
Explicit content filter level |
246
|
|
|
features: List[:class:`~pincer.objects.guild.features.GuildFeature`] |
247
|
|
|
Enabled guild features |
248
|
|
|
id: :class:`~pincer.utils.snowflake.Snowflake` |
249
|
|
|
Guild id |
250
|
|
|
icon: Optional[:class:`str`] |
251
|
|
|
Icon hash |
252
|
|
|
mfa_level: :class:`~pincer.objects.guild.guild.MFALevel` |
253
|
|
|
Required MFA level for the guild |
254
|
|
|
name: :class:`str` |
255
|
|
|
Guild name (2-100 characters, excluding trailing and leading |
256
|
|
|
whitespace) |
257
|
|
|
nsfw_level: :class:`~pincer.objects.guild.guild.NSFWLevel` |
258
|
|
|
Guild NSFW level |
259
|
|
|
owner_id: :class:`~pincer.utils.snowflake.Snowflake` |
260
|
|
|
Id of owner |
261
|
|
|
preferred_locale: :class:`str` |
262
|
|
|
The preferred locale of a Community guild; |
263
|
|
|
used in server discovery and notices from Discord; |
264
|
|
|
defaults to "en-US" |
265
|
|
|
premium_tier: :class:`~pincer.objects.guild.guild.PremiumTier` |
266
|
|
|
Premium tier (Server Boost level) |
267
|
|
|
public_updates_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`] |
268
|
|
|
The id of the channel where admins |
269
|
|
|
and moderators of Community guilds receive notices from Discord |
270
|
|
|
roles: List[:class:`~pincer.objects.guild.role.Role`] |
271
|
|
|
Roles in the guild |
272
|
|
|
rules_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`] |
273
|
|
|
The id of the channel where Community guilds can display rules |
274
|
|
|
and/or guidelines |
275
|
|
|
splash: Optional[:class:`str`] |
276
|
|
|
Splash hash |
277
|
|
|
system_channel_flags: :class:`~pincer.objects.guild.guild.SystemChannelFlags` |
278
|
|
|
System channel flags |
279
|
|
|
system_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`] |
280
|
|
|
The id of the channel where guild notices |
281
|
|
|
such as welcome messages and boost events are posted |
282
|
|
|
vanity_url_code: Optional[:class:`str`] |
283
|
|
|
The vanity url code for the guild |
284
|
|
|
verification_level: :class:`~pincer.objects.guild.guild.VerificationLevel` |
285
|
|
|
Verification level required for the guild |
286
|
|
|
approximate_member_count: APINullable[:class:`int`] |
287
|
|
|
Approximate number of members in this guild, returned from the |
288
|
|
|
`GET /guilds/<id>` endpoint when with_counts is true |
289
|
|
|
approximate_presence_count: APINullable[:class:`int`] |
290
|
|
|
Approximate number of non-offline members in this guild, |
291
|
|
|
returned from the `GET /guilds/<id>` |
292
|
|
|
endpoint when with_counts is true |
293
|
|
|
channels: APINullable[List[:class:`~pincer.objects.guild.channel.Channel`]] |
294
|
|
|
Channels in the guild |
295
|
|
|
icon_hash: APINullable[Optional[:class:`str`]] |
296
|
|
|
Icon hash, returned when in the template object |
297
|
|
|
joined_at: APINullable[:class:`~pincer.utils.timestamp.Timestamp`] |
298
|
|
|
When this guild was joined at |
299
|
|
|
large: APINullable[:class:`bool`] |
300
|
|
|
True if this is considered a large guild |
301
|
|
|
max_members: APINullable[:class:`int`] |
302
|
|
|
The maximum number of members for the guild |
303
|
|
|
max_presences: APINullable[Optional[:class:`int`]] |
304
|
|
|
The maximum number of presences for the guild |
305
|
|
|
(null is always returned, apart from the largest of guilds) |
306
|
|
|
max_video_channel_users: APINullable[:class:`int`] |
307
|
|
|
The maximum amount of users in a video channel |
308
|
|
|
members: APINullable[List[:class:`~pincer.objects.guild.member.GuildMember`]] |
309
|
|
|
Users in the guild |
310
|
|
|
member_count: APINullable[:class:`bool`] |
311
|
|
|
Total number of members in this guild |
312
|
|
|
nsfw: APINullable[:class:`bool`] |
313
|
|
|
Boolean if the server is NSFW |
314
|
|
|
owner: APINullable[:class:`bool`] |
315
|
|
|
True if the user is the owner of the guild |
316
|
|
|
permissions: APINullable[:class:`str`] |
317
|
|
|
Total permissions for the user in the guild |
318
|
|
|
(excludes overwrites) |
319
|
|
|
premium_subscription_count: APINullable[:class:`int`] |
320
|
|
|
The number of boosts this guild currently has |
321
|
|
|
presences: APINullable[List[:class:`~pincer.objects.events.presence.PresenceUpdateEvent`]] |
322
|
|
|
Presences of the members in the guild, |
323
|
|
|
will only include non-offline members if the size is greater |
324
|
|
|
than large threshold |
325
|
|
|
stage_instances: APINullable[List[:class:`~pincer.objects.guild.stage.StageInstance`]] |
326
|
|
|
Stage instances in the guild |
327
|
|
|
stickers: Optional[List[:class:`~pincer.objects.message.sticker.Sticker`]] |
328
|
|
|
Custom guild stickers |
329
|
|
|
region: APINullable[Optional[:class:`str`]] |
330
|
|
|
Voice region id for the guild (deprecated) |
331
|
|
|
threads: APINullable[List[:class:`~pincer.objects.guild.channel.Channel`]] |
332
|
|
|
All active threads in the guild that current user |
333
|
|
|
has permission to view |
334
|
|
|
unavailable: APINullable[:class:`bool`] |
335
|
|
|
True if this guild is unavailable due to an outage |
336
|
|
|
voice_states: APINullable[List[:class:`~pincer.objects.user.voice_state.VoiceState`]] |
337
|
|
|
States of members currently in voice channels; |
338
|
|
|
lacks the guild_id key |
339
|
|
|
widget_enabled: APINullable[:class:`bool`] |
340
|
|
|
True if the server widget is enabled |
341
|
|
|
widget_channel_id: APINullable[Optional[:class:`~pincer.utils.snowflake.Snowflake`]] |
342
|
|
|
The channel id that the widget will generate an invite to, |
343
|
|
|
or null if set to no invite |
344
|
|
|
welcome_screen: APINullable[:class:`~pincer.objects.guild.welcome_screen.WelcomeScreen`] |
345
|
|
|
The welcome screen of a Community guild, shown to new members, |
346
|
|
|
returned in an Invite's guild object |
347
|
|
|
""" |
348
|
|
|
|
349
|
|
|
# noqa: E501 |
350
|
|
|
features: List[GuildFeature] |
351
|
|
|
id: Snowflake |
352
|
|
|
name: str |
353
|
|
|
nsfw_level: GuildNSFWLevel |
354
|
|
|
verification_level: VerificationLevel |
355
|
|
|
|
356
|
|
|
# Guild invites missing |
357
|
|
|
system_channel_flags: APINullable[SystemChannelFlags] = MISSING |
358
|
|
|
explicit_content_filter: APINullable[ExplicitContentFilterLevel] = MISSING |
359
|
|
|
premium_tier: APINullable[PremiumTier] = MISSING |
360
|
|
|
default_message_notifications: APINullable[ |
361
|
|
|
DefaultMessageNotificationLevel |
362
|
|
|
] = MISSING |
363
|
|
|
mfa_level: APINullable[MFALevel] = MISSING |
364
|
|
|
owner_id: APINullable[Snowflake] = MISSING |
365
|
|
|
afk_timeout: APINullable[int] = MISSING |
366
|
|
|
emojis: APINullable[List[Emoji]] = MISSING |
367
|
|
|
preferred_locale: APINullable[str] = MISSING |
368
|
|
|
roles: APINullable[List[Role]] = MISSING |
369
|
|
|
|
370
|
|
|
guild_scheduled_events: APINullable[List[ScheduledEvent]] = MISSING |
371
|
|
|
lazy: APINullable[bool] = MISSING |
372
|
|
|
premium_progress_bar_enabled: APINullable[bool] = MISSING |
373
|
|
|
guild_hashes: APINullable[Dict] = MISSING |
374
|
|
|
afk_channel_id: APINullable[Snowflake] = MISSING |
375
|
|
|
application_id: APINullable[Snowflake] = MISSING |
376
|
|
|
embedded_activities: APINullable[List] = MISSING |
377
|
|
|
banner: APINullable[str] = MISSING |
378
|
|
|
description: APINullable[str] = MISSING |
379
|
|
|
discovery_splash: APINullable[str] = MISSING |
380
|
|
|
icon: APINullable[str] = MISSING |
381
|
|
|
public_updates_channel_id: APINullable[Snowflake] = MISSING |
382
|
|
|
rules_channel_id: APINullable[Snowflake] = MISSING |
383
|
|
|
splash: APINullable[str] = MISSING |
384
|
|
|
system_channel_id: APINullable[Snowflake] = MISSING |
385
|
|
|
vanity_url_code: APINullable[str] = MISSING |
386
|
|
|
|
387
|
|
|
application_command_counts: APINullable[Dict] = MISSING |
388
|
|
|
application_command_count: APINullable[int] = MISSING |
389
|
|
|
approximate_member_count: APINullable[int] = MISSING |
390
|
|
|
approximate_presence_count: APINullable[int] = MISSING |
391
|
|
|
channels: APINullable[List[Channel]] = field(default_factory=list) |
392
|
|
|
# TODO: Add type when type is known |
|
|
|
|
393
|
|
|
hub_type: APINullable[Any] = MISSING |
394
|
|
|
icon_hash: APINullable[Optional[str]] = MISSING |
395
|
|
|
joined_at: APINullable[Timestamp] = MISSING |
396
|
|
|
large: APINullable[bool] = MISSING |
397
|
|
|
max_members: APINullable[int] = MISSING |
398
|
|
|
max_presences: APINullable[Optional[int]] = MISSING |
399
|
|
|
max_video_channel_users: APINullable[int] = MISSING |
400
|
|
|
members: APINullable[List[GuildMember]] = MISSING |
401
|
|
|
member_count: APINullable[bool] = MISSING |
402
|
|
|
nsfw: APINullable[bool] = MISSING |
403
|
|
|
# Note: This is missing from discord's docs but in the api |
404
|
|
|
owner: APINullable[bool] = MISSING |
405
|
|
|
permissions: APINullable[str] = MISSING |
406
|
|
|
premium_subscription_count: APINullable[int] = MISSING |
407
|
|
|
presences: APINullable[List[PresenceUpdateEvent]] = MISSING |
408
|
|
|
stage_instances: APINullable[List[StageInstance]] = MISSING |
409
|
|
|
stickers: APINullable[List[Sticker]] = MISSING |
410
|
|
|
region: APINullable[Optional[str]] = MISSING |
411
|
|
|
threads: APINullable[List[Channel]] = MISSING |
412
|
|
|
# Guilds are considered available unless otherwise specified |
413
|
|
|
unavailable: APINullable[bool] = False |
414
|
|
|
voice_states: APINullable[List[VoiceState]] = MISSING |
415
|
|
|
widget_enabled: APINullable[bool] = MISSING |
416
|
|
|
widget_channel_id: APINullable[Optional[Snowflake]] = MISSING |
417
|
|
|
welcome_screen: APINullable[WelcomeScreen] = MISSING |
418
|
|
|
|
419
|
|
|
@classmethod |
420
|
|
|
async def from_id( |
421
|
|
|
cls, |
|
|
|
|
422
|
|
|
client: Client, |
|
|
|
|
423
|
|
|
_id: Union[int, Snowflake], |
|
|
|
|
424
|
|
|
with_counts: bool = False, |
|
|
|
|
425
|
|
|
) -> Guild: |
426
|
|
|
""" |
427
|
|
|
Parameters |
428
|
|
|
---------- |
429
|
|
|
client : :class:`~pincer.Client` |
430
|
|
|
Client object to use the http gateway from. |
431
|
|
|
_id : :class:`~pincer.utils.snowflake.Snowflake` |
432
|
|
|
Guild ID. |
433
|
|
|
with_counts : :class:`bool` |
434
|
|
|
Whether to fetch approximate member and presence counts. |
435
|
|
|
|
436
|
|
|
Returns |
437
|
|
|
------- |
438
|
|
|
:class:`~pincer.objects.guild.guild.Guild` |
439
|
|
|
The new guild object. |
440
|
|
|
""" |
441
|
|
|
data = await client.http.get( |
442
|
|
|
f"/guilds/{_id}", |
443
|
|
|
# Yarl don't support boolean params |
444
|
|
|
params={"with_counts": "true" if with_counts else None}, |
445
|
|
|
) |
446
|
|
|
channel_data = await client.http.get(f"/guilds/{_id}/channels") |
447
|
|
|
|
448
|
|
|
data["channels"]: List[Channel] = [ |
449
|
|
|
Channel.from_dict(i) for i in (channel_data or []) |
450
|
|
|
] |
451
|
|
|
|
452
|
|
|
return Guild.from_dict(data) |
453
|
|
|
|
454
|
|
|
async def get_member(self, _id: int) -> GuildMember: |
455
|
|
|
"""|coro| |
456
|
|
|
Fetches a GuildMember from its identifier |
457
|
|
|
|
458
|
|
|
Parameters |
459
|
|
|
---------- |
460
|
|
|
_id: int |
461
|
|
|
The id of the guild member which should be fetched from the Discord |
462
|
|
|
gateway. |
463
|
|
|
Returns |
464
|
|
|
------- |
465
|
|
|
:class:`~pincer.objects.guild.member.GuildMember` |
466
|
|
|
A GuildMember object. |
467
|
|
|
""" |
468
|
|
|
return await GuildMember.from_id(self._client, self.id, _id) |
469
|
|
|
|
470
|
|
|
@overload |
471
|
|
|
async def modify_member( |
472
|
|
|
self, |
|
|
|
|
473
|
|
|
*, |
|
|
|
|
474
|
|
|
_id: int, |
|
|
|
|
475
|
|
|
nick: Optional[str] = None, |
|
|
|
|
476
|
|
|
roles: Optional[List[Snowflake]] = None, |
|
|
|
|
477
|
|
|
mute: Optional[bool] = None, |
|
|
|
|
478
|
|
|
deaf: Optional[bool] = None, |
|
|
|
|
479
|
|
|
channel_id: Optional[Snowflake] = None, |
|
|
|
|
480
|
|
|
reason: Optional[str] = None, |
|
|
|
|
481
|
|
|
communication_disabled_until: Optional[Timestamp] = MISSING, |
|
|
|
|
482
|
|
|
) -> GuildMember: |
483
|
|
|
"""|coro| |
484
|
|
|
Modifies a member in the guild from its identifier and based on the |
485
|
|
|
keyword arguments provided. |
486
|
|
|
Parameters |
487
|
|
|
---------- |
488
|
|
|
_id : int |
489
|
|
|
Id of the member to modify |
490
|
|
|
nick : Optional[:class:`str`] |
491
|
|
|
New nickname for the member |default| :data:`None` |
492
|
|
|
roles : Optional[List[:class:`~pincer.utils.snowflake.Snowflake]] |
493
|
|
|
New roles for the member |default| :data:`None` |
494
|
|
|
mute : Optional[:class:`bool`] |
495
|
|
|
Whether the member is muted |default| :data:`None` |
496
|
|
|
deaf : Optional[:class:`bool`] |
497
|
|
|
Whether the member is deafened |default| :data:`None` |
498
|
|
|
channel_id : Optional[:class:`~pincer.utils.snowflake.Snowflake] |
499
|
|
|
Voice channel id to move to |default| :data:`None` |
500
|
|
|
reason : Optional[:class:`str`] |
501
|
|
|
audit log reason |default| :data:`None` |
502
|
|
|
communication_disabled_until : Optional[Timestamp] |
503
|
|
|
When the member can communicate again, requires ``MODERATE_MEMBERS`` |
504
|
|
|
permissions. Set to ``None`` to disable the timeout. |
505
|
|
|
|
506
|
|
|
Returns |
507
|
|
|
------- |
508
|
|
|
:class:`~pincer.objects.guild.member.GuildMember` |
509
|
|
|
The new member object. |
510
|
|
|
""" |
511
|
|
|
... |
512
|
|
|
|
513
|
|
|
async def modify_member( |
|
|
|
|
514
|
|
|
self, _id: int, reason=None, **kwargs |
|
|
|
|
515
|
|
|
) -> GuildMember: |
516
|
|
|
if kwargs.get("communication_disabled_until") is MISSING: |
517
|
|
|
kwargs.pop("communication_disabled_until") |
518
|
|
|
data = await self._http.patch( |
519
|
|
|
f"guilds/{self.id}/members/{_id}", |
520
|
|
|
data=kwargs, |
521
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
522
|
|
|
) |
523
|
|
|
return GuildMember.from_dict(data) |
524
|
|
|
|
525
|
|
|
@overload |
526
|
|
|
async def create_channel( |
527
|
|
|
self, |
|
|
|
|
528
|
|
|
*, |
|
|
|
|
529
|
|
|
name: str, |
|
|
|
|
530
|
|
|
type: Optional[ChannelType] = None, |
|
|
|
|
531
|
|
|
topic: Optional[str] = None, |
|
|
|
|
532
|
|
|
bitrate: Optional[int] = None, |
|
|
|
|
533
|
|
|
user_limit: Optional[int] = None, |
|
|
|
|
534
|
|
|
rate_limit_per_user: Optional[int] = None, |
|
|
|
|
535
|
|
|
position: Optional[int] = None, |
|
|
|
|
536
|
|
|
permission_overwrites: Optional[List[Overwrite]] = None, |
|
|
|
|
537
|
|
|
parent_id: Optional[Snowflake] = None, |
|
|
|
|
538
|
|
|
nsfw: Optional[bool] = None, |
|
|
|
|
539
|
|
|
) -> Channel: |
540
|
|
|
"""|coro| |
541
|
|
|
Create a new channel object for the guild. |
542
|
|
|
|
543
|
|
|
Parameters |
544
|
|
|
---------- |
545
|
|
|
name : str |
546
|
|
|
channel name (1-100 characters) |
547
|
|
|
type : Optional[:class:int`] |
548
|
|
|
the type of channel |
549
|
|
|
topic : Optional[:class:str`] |
550
|
|
|
channel topic (0-1024 characters) |
551
|
|
|
bitrate : Optional[:class:`int`] |
552
|
|
|
the bitrate (in bits) of the voice channel (voice only) |
553
|
|
|
user_limit : Optional[:class:`int`] |
554
|
|
|
the user limit of the voice channel (voice only) |
555
|
|
|
rate_limit_per_user : Optional[:class:`int`] |
556
|
|
|
amount of seconds a user has to wait |
557
|
|
|
before sending another message (0-21600) |
558
|
|
|
bots, as well as users with the permission |
559
|
|
|
manage_messages or manage_channel, are unaffected |
560
|
|
|
position : Optional[:class:`int`] |
561
|
|
|
sorting position of the channel |
562
|
|
|
permission_overwrites : Optional[List[:class:`~pincer.objects.guild.overwrite.Overwrite`]] |
563
|
|
|
the channel's permission overwrites |
564
|
|
|
parent_id : Optional[:class:`~pincer.utils.snowflake.Snowflake`] |
565
|
|
|
id of the parent category for a channel |
566
|
|
|
nsfw : Optional[:class:`bool`] |
567
|
|
|
whether the channel is nsfw |
568
|
|
|
reason : Optional[:class:`str`] |
569
|
|
|
audit log reason |default| :data:`None` |
570
|
|
|
Returns |
571
|
|
|
------- |
572
|
|
|
:class:`~pincer.objects.guild.channel.Channel` |
573
|
|
|
The new channel object. |
574
|
|
|
""" |
575
|
|
|
... |
576
|
|
|
|
577
|
|
|
async def create_channel(self, *, reason: Optional[str] = None, **kwargs): |
|
|
|
|
578
|
|
|
data = await self._http.post( |
579
|
|
|
f"guilds/{self.id}/channels", |
580
|
|
|
data=kwargs, |
581
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
582
|
|
|
) |
583
|
|
|
return Channel.from_dict(data) |
584
|
|
|
|
585
|
|
|
async def modify_channel_positions( |
|
|
|
|
586
|
|
|
self, |
|
|
|
|
587
|
|
|
reason: Optional[str] = None, |
|
|
|
|
588
|
|
|
*channel: Dict[str, Optional[Union[int, bool, Snowflake]]], |
|
|
|
|
589
|
|
|
): |
590
|
|
|
"""|coro| |
591
|
|
|
Create a new channel object for the guild. |
592
|
|
|
|
593
|
|
|
Parameters |
594
|
|
|
---------- |
595
|
|
|
reason : Optional[:class:`str`] |
596
|
|
|
audit log reason |default| :data:`None` |
597
|
|
|
\\*channel : Dict[str, Optional[Union[int, bool, :class:`~pincer.utils.snowflake.Snowflake`] |
598
|
|
|
Keys: |
599
|
|
|
- id : :class:`~pincer.utils.snowflake.Snowflake` |
600
|
|
|
- position : Optional[:class:`int`] |
601
|
|
|
- lock_permissions : Optional[:class:`bool`] |
602
|
|
|
- parent_id : Optional[:class:`~pincer.utils.snowflake.Snowflake`] |
603
|
|
|
""" |
604
|
|
|
await self._http.patch( |
605
|
|
|
f"guilds/{self.id}/channels", |
606
|
|
|
data=channel, |
607
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
608
|
|
|
) |
609
|
|
|
|
610
|
|
|
async def list_active_threads( |
611
|
|
|
self, |
|
|
|
|
612
|
|
|
) -> Tuple[Generator[Thread], Generator[GuildMember]]: |
613
|
|
|
"""|coro| |
614
|
|
|
Returns all active threads in the guild, |
615
|
|
|
including public and private threads. |
616
|
|
|
|
617
|
|
|
Returns |
618
|
|
|
------- |
619
|
|
|
Generator[Union[:class:`~pincer.objects.guild.channel.PublicThread`, :class:`~pincer.objects.guild.channel.PrivateThread`]], Generator[:class:`~pincer.objects.guild.member.GuildMember`]] |
|
|
|
|
620
|
|
|
The new member object. |
621
|
|
|
""" |
622
|
|
|
data = await self._http.get(f"guilds/{self.id}/threads/active") |
623
|
|
|
|
624
|
|
|
threads = (Channel.from_dict(channel) for channel in data["threads"]) |
625
|
|
|
members = (GuildMember.from_dict(member) for member in data["members"]) |
626
|
|
|
|
627
|
|
|
return threads, members |
628
|
|
|
|
629
|
|
|
def list_guild_members( |
630
|
|
|
self, limit: int = 1, after: int = 0 |
|
|
|
|
631
|
|
|
) -> APIDataGen[GuildMember]: |
632
|
|
|
"""|coro| |
633
|
|
|
Returns a list of guild member objects that are members of the guild. |
634
|
|
|
|
635
|
|
|
Parameters |
636
|
|
|
---------- |
637
|
|
|
limit : int |
638
|
|
|
max number of members to return (1-1000) |default| :data:`1` |
639
|
|
|
after : int |
640
|
|
|
the highest user id in the previous page |default| :data:`0` |
641
|
|
|
|
642
|
|
|
Yields |
643
|
|
|
------ |
644
|
|
|
:class:`~pincer.objects.guild.member.GuildMember` |
645
|
|
|
the guild member object that is in the guild |
646
|
|
|
""" |
647
|
|
|
|
648
|
|
|
return APIDataGen( |
649
|
|
|
GuildMember, |
650
|
|
|
self._http.get( |
651
|
|
|
f"guilds/{self.id}/members", |
652
|
|
|
params={"limit": limit, "after": after}, |
653
|
|
|
), |
654
|
|
|
) |
655
|
|
|
|
656
|
|
|
def search_guild_members( |
657
|
|
|
self, query: str, limit: Optional[int] = None |
|
|
|
|
658
|
|
|
) -> APIDataGen[GuildMember]: |
659
|
|
|
"""|coro| |
660
|
|
|
Returns a list of guild member objects whose |
661
|
|
|
username or nickname starts with a provided string. |
662
|
|
|
|
663
|
|
|
Parameters |
664
|
|
|
---------- |
665
|
|
|
query : str |
666
|
|
|
Query string to match username(s) and nickname(s) against. |
667
|
|
|
limit : Optional[int] |
668
|
|
|
max number of members to return (1-1000) |default| :data:`1` |
669
|
|
|
|
670
|
|
|
Yields |
671
|
|
|
------- |
672
|
|
|
:class:`~pincer.objects.guild.member.GuildMember` |
673
|
|
|
guild member objects |
674
|
|
|
""" |
675
|
|
|
|
676
|
|
|
return APIDataGen( |
677
|
|
|
GuildMember, |
678
|
|
|
self._http.get( |
679
|
|
|
f"guilds/{self.id}/members/search", |
680
|
|
|
params={"query": query, "limit": limit}, |
681
|
|
|
), |
682
|
|
|
) |
683
|
|
|
|
684
|
|
|
@overload |
685
|
|
|
async def add_guild_member( |
686
|
|
|
self, |
|
|
|
|
687
|
|
|
*, |
|
|
|
|
688
|
|
|
user_id: Snowflake, |
|
|
|
|
689
|
|
|
access_token: str, |
|
|
|
|
690
|
|
|
nick: Optional[str] = None, |
|
|
|
|
691
|
|
|
roles: Optional[List[Snowflake]] = None, |
|
|
|
|
692
|
|
|
mute: Optional[bool] = None, |
|
|
|
|
693
|
|
|
deaf: Optional[bool] = None, |
|
|
|
|
694
|
|
|
reason: Optional[str] = None, |
|
|
|
|
695
|
|
|
) -> Optional[GuildMember]: |
696
|
|
|
"""|coro| |
697
|
|
|
Adds a user to the guild, provided you have a |
698
|
|
|
valid oauth2 access token for the user with the guilds.join scope. |
699
|
|
|
|
700
|
|
|
Parameters |
701
|
|
|
---------- |
702
|
|
|
user_id : str |
703
|
|
|
id of the user to be added |
704
|
|
|
access_token : str |
705
|
|
|
an oauth2 access token granted with the guilds.join to |
706
|
|
|
the bot's application for the user you want to add to the guild |
707
|
|
|
nick : Optional[str] |
708
|
|
|
value to set users nickname to |
709
|
|
|
roles : Optional[List[:class:`~pincer.utils.snowflake.Snowflake`]] |
710
|
|
|
array of role ids the member is assigned |
711
|
|
|
mute : Optional[bool] |
712
|
|
|
whether the user is muted in voice channels |
713
|
|
|
deaf : Optional[bool] |
714
|
|
|
whether the user is deafened in voice channels |
715
|
|
|
reason : Optional[:class:`str`] |
716
|
|
|
audit log reason |default| :data:`None` |
717
|
|
|
Returns |
718
|
|
|
------- |
719
|
|
|
:class:`~pincer.objects.guild.member.GuildMember` |
720
|
|
|
If the user is not in the guild |
721
|
|
|
None |
722
|
|
|
If the user is in the guild |
723
|
|
|
""" |
724
|
|
|
|
725
|
|
|
async def add_guild_member(self, user_id, reason=None, **kwargs): |
|
|
|
|
726
|
|
|
data = await self._http.put( |
727
|
|
|
f"guilds/{self.id}/members/{user_id}", |
728
|
|
|
data=kwargs, |
729
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
730
|
|
|
) |
731
|
|
|
|
732
|
|
|
return GuildMember.from_dict(data) if data else None |
733
|
|
|
|
734
|
|
|
async def modify_current_member( |
735
|
|
|
self, nick: str, reason: Optional[str] = None |
|
|
|
|
736
|
|
|
) -> GuildMember: |
737
|
|
|
"""|coro| |
738
|
|
|
Modifies the current member in a guild. |
739
|
|
|
|
740
|
|
|
Parameters |
741
|
|
|
---------- |
742
|
|
|
nick : str |
743
|
|
|
value to set users nickname to |
744
|
|
|
reason : Optional[:class:`str`] |
745
|
|
|
audit log reason |default| :data:`None` |
746
|
|
|
Returns |
747
|
|
|
------- |
748
|
|
|
class:`~pincer.objects.guild.member.GuildMember |
749
|
|
|
current guild member |
750
|
|
|
""" |
751
|
|
|
data = self._http.patch( |
752
|
|
|
f"guilds/{self.id}/members/@me", |
753
|
|
|
{"nick": nick}, |
754
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
755
|
|
|
) |
756
|
|
|
return GuildMember.from_dict(data) |
757
|
|
|
|
758
|
|
|
async def add_guild_member_role( |
759
|
|
|
self, user_id: int, role_id: int, reason: Optional[str] = None |
|
|
|
|
760
|
|
|
) -> None: |
761
|
|
|
"""|coro| |
762
|
|
|
Adds a role to a guild member. |
763
|
|
|
|
764
|
|
|
Parameters |
765
|
|
|
---------- |
766
|
|
|
user_id : int |
767
|
|
|
id of the user to give a role to |
768
|
|
|
role_id : int |
769
|
|
|
id of a role |
770
|
|
|
reason : Optional[:class:`str`] |
771
|
|
|
audit log reason |default| :data:`None` |
772
|
|
|
""" |
773
|
|
|
await self._http.put( |
774
|
|
|
f"guilds/{self.id}/members/{user_id}/roles/{role_id}", |
775
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
776
|
|
|
) |
777
|
|
|
|
778
|
|
|
async def remove_guild_member_role( |
779
|
|
|
self, user_id: int, role_id: int, reason: Optional[str] = None |
|
|
|
|
780
|
|
|
): |
781
|
|
|
"""|coro| |
782
|
|
|
Removes a role from a guild member. |
783
|
|
|
|
784
|
|
|
Parameters |
785
|
|
|
---------- |
786
|
|
|
user_id : int |
787
|
|
|
id of the user to remove a role from |
788
|
|
|
role_id : int |
789
|
|
|
id of a role |
790
|
|
|
reason : Optional[:class:`str`] |
791
|
|
|
audit log reason |default| :data:`None` |
792
|
|
|
""" |
793
|
|
|
await self._http.delete( |
794
|
|
|
f"guilds/{self.id}/members/{user_id}/roles/{role_id}", |
795
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
796
|
|
|
) |
797
|
|
|
|
798
|
|
|
async def remove_guild_member( |
799
|
|
|
self, user_id: int, reason: Optional[str] = None |
|
|
|
|
800
|
|
|
): |
801
|
|
|
"""|coro| |
802
|
|
|
Remove a member from a guild. |
803
|
|
|
|
804
|
|
|
Parameters |
805
|
|
|
---------- |
806
|
|
|
user_id : int |
807
|
|
|
id of the user to remove from the guild |
808
|
|
|
reason : Optional[:class:`str`] |
809
|
|
|
audit log reason |default| :data:`None` |
810
|
|
|
""" |
811
|
|
|
await self._http.delete( |
812
|
|
|
f"guilds/{self.id}/members/{user_id}", |
813
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
814
|
|
|
) |
815
|
|
|
|
816
|
|
|
async def ban( |
817
|
|
|
self, |
|
|
|
|
818
|
|
|
member: Union[int, GuildMember], |
|
|
|
|
819
|
|
|
reason: str = None, |
|
|
|
|
820
|
|
|
delete_message_days: int = None, |
|
|
|
|
821
|
|
|
): |
822
|
|
|
""" |
823
|
|
|
Ban a guild member. |
824
|
|
|
|
825
|
|
|
Parameters |
826
|
|
|
---------- |
827
|
|
|
member : Union[:class:`int`, :class:`GuildMember`] |
828
|
|
|
ID or object of the guild member to ban. |
829
|
|
|
reason : Optional[:class:`str`] |
830
|
|
|
Reason for the kick. |
831
|
|
|
delete_message_days : Optional[:class:`int`] |
832
|
|
|
Number of days to delete messages for (0-7) |
833
|
|
|
""" |
834
|
|
|
headers = {} |
835
|
|
|
member_id: int = member if isinstance(member, int) else member.id |
836
|
|
|
|
837
|
|
|
if reason is not None: |
838
|
|
|
headers["X-Audit-Log-Reason"] = reason |
839
|
|
|
|
840
|
|
|
data = {} |
841
|
|
|
|
842
|
|
|
if delete_message_days is not None: |
843
|
|
|
data["delete_message_days"] = delete_message_days |
844
|
|
|
|
845
|
|
|
await self._http.put( |
846
|
|
|
f"/guilds/{self.id}/bans/{member_id}", data=data, headers=headers |
847
|
|
|
) |
848
|
|
|
|
849
|
|
|
async def kick( |
850
|
|
|
self, member: Union[int, GuildMember], reason: Optional[str] = None |
|
|
|
|
851
|
|
|
): |
852
|
|
|
"""|coro| |
853
|
|
|
Kicks a guild member. |
854
|
|
|
|
855
|
|
|
Parameters |
856
|
|
|
---------- |
857
|
|
|
member : Union[:class:`int`, :class:`GuildMember`] |
858
|
|
|
ID or object of the guild member to kick. |
859
|
|
|
reason : Optional[:class:`str`] |
860
|
|
|
Reason for the kick. |
861
|
|
|
""" |
862
|
|
|
headers = {} |
863
|
|
|
member_id: int = member if isinstance(member, int) else member.id |
864
|
|
|
|
865
|
|
|
if reason is not None: |
866
|
|
|
headers["X-Audit-Log-Reason"] = reason |
867
|
|
|
|
868
|
|
|
await self._http.delete( |
869
|
|
|
f"/guilds/{self.id}/members/{member_id}", headers=headers |
870
|
|
|
) |
871
|
|
|
|
872
|
|
|
def get_roles(self) -> APIDataGen[Role]: |
873
|
|
|
"""|coro| |
874
|
|
|
Fetches all the roles in the guild. |
875
|
|
|
|
876
|
|
|
Yields |
877
|
|
|
------- |
878
|
|
|
AsyncGenerator[:class:`~pincer.objects.guild.role.Role`, :data:`None`] |
879
|
|
|
An async generator of Role objects. |
880
|
|
|
""" |
881
|
|
|
|
882
|
|
|
return APIDataGen(Role, self._http.get(f"guilds/{self.id}/roles")) |
883
|
|
|
|
884
|
|
|
@overload |
885
|
|
|
async def create_role( |
886
|
|
|
self, |
|
|
|
|
887
|
|
|
reason: Optional[str] = None, |
|
|
|
|
888
|
|
|
*, |
|
|
|
|
889
|
|
|
name: Optional[str] = "new role", |
|
|
|
|
890
|
|
|
permissions: Optional[str] = None, |
|
|
|
|
891
|
|
|
color: Optional[int] = 0, |
|
|
|
|
892
|
|
|
hoist: Optional[bool] = False, |
|
|
|
|
893
|
|
|
icon: Optional[str] = None, |
|
|
|
|
894
|
|
|
unicode_emoji: Optional[str] = None, |
|
|
|
|
895
|
|
|
mentionable: Optional[bool] = False, |
|
|
|
|
896
|
|
|
) -> Role: |
897
|
|
|
"""|coro| |
898
|
|
|
Creates a new role for the guild. |
899
|
|
|
Requires the ``MANAGE_ROLES`` permission. |
900
|
|
|
|
901
|
|
|
Parameters |
902
|
|
|
---------- |
903
|
|
|
reason : Optional[:class:`str`] |
904
|
|
|
Reason for creating the role. |default| :data:`None` |
905
|
|
|
name : Optional[:class:`str`] |
906
|
|
|
name of the role |default| :data:`"new role"` |
907
|
|
|
permissions : Optional[:class:`str`] |
908
|
|
|
bitwise value of the enabled/disabled |
909
|
|
|
permissions, set to @everyone permissions |
910
|
|
|
by default |default| :data:`None` |
911
|
|
|
color : Optional[:class:`int`] |
912
|
|
|
RGB color value |default| :data:`0` |
913
|
|
|
hoist : Optional[:class:`bool`] |
914
|
|
|
whether the role should be displayed |
915
|
|
|
separately in the sidebar |default| :data:`False` |
916
|
|
|
icon : Optional[:class:`str`] |
917
|
|
|
the role's icon image (if the guild has |
918
|
|
|
the ``ROLE_ICONS`` feature) |default| :data:`None` |
919
|
|
|
unicode_emoji : Optional[:class:`str`] |
920
|
|
|
the role's unicode emoji as a standard emoji (if the guild |
921
|
|
|
has the ``ROLE_ICONS`` feature) |default| :data:`None` |
922
|
|
|
mentionable : Optional[:class:`bool`] |
923
|
|
|
whether the role should be mentionable |default| :data:`False` |
924
|
|
|
|
925
|
|
|
Returns |
926
|
|
|
------- |
927
|
|
|
:class:`~pincer.objects.guild.role.Role` |
928
|
|
|
The new role object. |
929
|
|
|
""" |
930
|
|
|
... |
931
|
|
|
|
932
|
|
|
async def create_role(self, reason: Optional[str] = None, **kwargs) -> Role: |
|
|
|
|
933
|
|
|
return Role.from_dict( |
934
|
|
|
await self._http.post( |
935
|
|
|
f"guilds/{self.id}/roles", |
936
|
|
|
data=kwargs, |
937
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
938
|
|
|
) |
939
|
|
|
) |
940
|
|
|
|
941
|
|
|
def edit_role_position( |
942
|
|
|
self, |
|
|
|
|
943
|
|
|
id: Snowflake, |
|
|
|
|
944
|
|
|
reason: Optional[str] = None, |
|
|
|
|
945
|
|
|
position: Optional[int] = None, |
|
|
|
|
946
|
|
|
) -> APIDataGen[Role]: |
947
|
|
|
"""|coro| |
948
|
|
|
Edits the position of a role. |
949
|
|
|
|
950
|
|
|
Parameters |
951
|
|
|
---------- |
952
|
|
|
id : :class:`~pincer.utils.snowflake.Snowflake` |
953
|
|
|
The role ID |
954
|
|
|
reason : Optional[:class:`str`] |
955
|
|
|
Reason for editing the role position. |default| :data:`None` |
956
|
|
|
position : Optional[:class:`int`] |
957
|
|
|
Sorting position of the role |default| :data:`None` |
958
|
|
|
|
959
|
|
|
Yields |
960
|
|
|
------- |
961
|
|
|
AsyncGenerator[:class:`~pincer.objects.guild.role.Role`, :data:`None`] |
962
|
|
|
An async generator of all the guild's role objects. |
963
|
|
|
""" |
964
|
|
|
return APIDataGen( |
965
|
|
|
Role, |
966
|
|
|
self._http.patch( |
967
|
|
|
f"guilds/{self.id}/roles", |
968
|
|
|
data={"id": id, "position": position}, |
969
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
970
|
|
|
), |
971
|
|
|
) |
972
|
|
|
|
973
|
|
|
@overload |
974
|
|
|
async def edit_role( |
975
|
|
|
self, |
|
|
|
|
976
|
|
|
id: Snowflake, |
|
|
|
|
977
|
|
|
reason: Optional[str] = None, |
|
|
|
|
978
|
|
|
*, |
|
|
|
|
979
|
|
|
name: Optional[str] = None, |
|
|
|
|
980
|
|
|
permissions: Optional[str] = None, |
|
|
|
|
981
|
|
|
color: Optional[int] = None, |
|
|
|
|
982
|
|
|
hoist: Optional[bool] = None, |
|
|
|
|
983
|
|
|
icon: Optional[str] = None, |
|
|
|
|
984
|
|
|
unicode_emoji: Optional[str] = None, |
|
|
|
|
985
|
|
|
mentionable: Optional[bool] = None, |
|
|
|
|
986
|
|
|
) -> Role: |
987
|
|
|
"""|coro| |
988
|
|
|
Edits a role. |
989
|
|
|
Requires the ``MANAGE_ROLES`` permission. |
990
|
|
|
|
991
|
|
|
Parameters |
992
|
|
|
---------- |
993
|
|
|
id : :class:`~pincer.utils.snowflake.Snowflake` |
994
|
|
|
The role ID |
995
|
|
|
reason : Optional[:class:`str`] |
996
|
|
|
Reason for editing the role |default| :data:`None` |
997
|
|
|
name : Optional[:class:`str`] |
998
|
|
|
Name of the role |default| :data:`None` |
999
|
|
|
permissions : Optional[:class:`str`] |
1000
|
|
|
Bitwise value of the enabled/disabled |
1001
|
|
|
permissions |default| :data:`None` |
1002
|
|
|
color : Optional[:class:`int`] |
1003
|
|
|
RGB color value |default| :data:`None` |
1004
|
|
|
hoist : Optional[:class:`bool`] |
1005
|
|
|
Whether the role should be displayed |
1006
|
|
|
separately in the sidebar |default| :data:`None` |
1007
|
|
|
icon : Optional[:class:`str`] |
1008
|
|
|
The role's icon image (if the guild has |
1009
|
|
|
the ``ROLE_ICONS`` feature) |default| :data:`None` |
1010
|
|
|
unicode_emoji : Optional[:class:`str`] |
1011
|
|
|
The role's unicode emoji as a standard emoji (if the guild |
1012
|
|
|
has the ``ROLE_ICONS`` feature) |default| :data:`None` |
1013
|
|
|
mentionable : Optional[:class:`bool`] |
1014
|
|
|
Whether the role should be mentionable |default| :data:`None` |
1015
|
|
|
|
1016
|
|
|
Returns |
1017
|
|
|
------- |
1018
|
|
|
:class:`~pincer.objects.guild.role.Role` |
1019
|
|
|
The edited role object. |
1020
|
|
|
""" |
1021
|
|
|
... |
1022
|
|
|
|
1023
|
|
|
async def edit_role( |
|
|
|
|
1024
|
|
|
self, id: Snowflake, reason: Optional[str] = None, **kwargs |
|
|
|
|
1025
|
|
|
) -> Role: |
1026
|
|
|
return Role.from_dict( |
1027
|
|
|
await self._http.patch( |
1028
|
|
|
f"guilds/{self.id}/roles/{id}", |
1029
|
|
|
data=kwargs, |
1030
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
1031
|
|
|
) |
1032
|
|
|
) |
1033
|
|
|
|
1034
|
|
|
async def delete_role(self, id: Snowflake, reason: Optional[str] = None): |
|
|
|
|
1035
|
|
|
"""|coro| |
1036
|
|
|
Deletes a role. |
1037
|
|
|
Requires the `MANAGE_ROLES` permission. |
1038
|
|
|
|
1039
|
|
|
Parameters |
1040
|
|
|
---------- |
1041
|
|
|
id : :class:`~pincer.utils.snowflake.Snowflake` |
1042
|
|
|
The role ID |
1043
|
|
|
reason : Optional[:class:`str`] |
1044
|
|
|
The reason for deleting the role |default| :data:`None` |
1045
|
|
|
""" |
1046
|
|
|
await self._http.delete( |
1047
|
|
|
f"guilds/{self.id}/roles/{id}", |
1048
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
1049
|
|
|
) |
1050
|
|
|
|
1051
|
|
|
def get_bans(self) -> APIDataGen[Ban]: |
1052
|
|
|
"""|coro| |
1053
|
|
|
Fetches all the bans in the guild. |
1054
|
|
|
|
1055
|
|
|
Yields |
1056
|
|
|
------- |
1057
|
|
|
AsyncGenerator[:class:`~pincer.objects.guild.ban.Ban`, :data:`None`] |
1058
|
|
|
An async generator of Ban objects. |
1059
|
|
|
""" |
1060
|
|
|
|
1061
|
|
|
return APIDataGen(Ban, self._http.get(f"guilds/{self.id}/bans")) |
1062
|
|
|
|
1063
|
|
|
async def get_ban(self, id: Snowflake) -> Ban: |
|
|
|
|
1064
|
|
|
"""|coro| |
1065
|
|
|
Fetches a ban from the guild. |
1066
|
|
|
|
1067
|
|
|
Parameters |
1068
|
|
|
---------- |
1069
|
|
|
id : :class:`~pincer.utils.snowflake.Snowflake` |
1070
|
|
|
The user ID |
1071
|
|
|
|
1072
|
|
|
Returns |
1073
|
|
|
------- |
1074
|
|
|
:class:`~pincer.objects.guild.ban.Ban` |
1075
|
|
|
The Ban object. |
1076
|
|
|
""" |
1077
|
|
|
return Ban.from_dict( |
1078
|
|
|
await self._http.get(f"guilds/{self.id}/bans/{id}") |
1079
|
|
|
) |
1080
|
|
|
|
1081
|
|
|
async def unban(self, id: Snowflake, reason: Optional[str] = None): |
|
|
|
|
1082
|
|
|
"""|coro| |
1083
|
|
|
Unbans a user from the guild. |
1084
|
|
|
|
1085
|
|
|
Parameters |
1086
|
|
|
---------- |
1087
|
|
|
id : :class:`~pincer.utils.snowflake.Snowflake` |
1088
|
|
|
The user ID |
1089
|
|
|
reason : Optional[:class:`str`] |
1090
|
|
|
The reason for unbanning the user |default| :data:`None` |
1091
|
|
|
""" |
1092
|
|
|
await self._http.delete( |
1093
|
|
|
f"guilds/{self.id}/bans/{id}", |
1094
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
1095
|
|
|
) |
1096
|
|
|
|
1097
|
|
|
@overload |
1098
|
|
|
async def edit( |
|
|
|
|
1099
|
|
|
self, |
|
|
|
|
1100
|
|
|
*, |
|
|
|
|
1101
|
|
|
name: Optional[str] = None, |
|
|
|
|
1102
|
|
|
region: Optional[str] = None, |
|
|
|
|
1103
|
|
|
verification_level: Optional[int] = None, |
|
|
|
|
1104
|
|
|
default_message_notifications: Optional[int] = None, |
|
|
|
|
1105
|
|
|
explicit_content_filter: Optional[int] = None, |
|
|
|
|
1106
|
|
|
afk_channel_id: Optional[Snowflake] = None, |
|
|
|
|
1107
|
|
|
afk_timeout: Optional[int] = None, |
|
|
|
|
1108
|
|
|
icon: Optional[str] = None, |
|
|
|
|
1109
|
|
|
owner_id: Optional[Snowflake] = None, |
|
|
|
|
1110
|
|
|
splash: Optional[str] = None, |
|
|
|
|
1111
|
|
|
discovery_splash: Optional[str] = None, |
|
|
|
|
1112
|
|
|
banner: Optional[str] = None, |
|
|
|
|
1113
|
|
|
system_channel_id: Optional[Snowflake] = None, |
|
|
|
|
1114
|
|
|
system_channel_flags: Optional[int] = None, |
|
|
|
|
1115
|
|
|
rules_channel_id: Optional[Snowflake] = None, |
|
|
|
|
1116
|
|
|
public_updates_channel_id: Optional[Snowflake] = None, |
|
|
|
|
1117
|
|
|
preferred_locale: Optional[str] = None, |
|
|
|
|
1118
|
|
|
features: Optional[List[GuildFeature]] = None, |
|
|
|
|
1119
|
|
|
description: Optional[str] = None, |
|
|
|
|
1120
|
|
|
) -> Guild: |
1121
|
|
|
"""|coro| |
1122
|
|
|
Modifies the guild |
1123
|
|
|
|
1124
|
|
|
Parameters |
1125
|
|
|
---------- |
1126
|
|
|
name : Optional[:class:`str`] |
1127
|
|
|
Guild name |default| :data:`None` |
1128
|
|
|
region : Optional[:class:`str`] |
1129
|
|
|
Guild voice region ID |default| :data:`None` |
1130
|
|
|
verification_level : Optional[:class:`int`] |
1131
|
|
|
Verification level |default| :data:`None` |
1132
|
|
|
default_message_notifications : Optional[:class:`int`] |
1133
|
|
|
Default message notification level |default| :data:`None` |
1134
|
|
|
explicit_content_filter : Optional[:class:`int`] |
1135
|
|
|
Explicit content filter level |default| :data:`None` |
1136
|
|
|
afk_channel_id : Optional[:class:`~pincer.utils.snowflake.Snowflake`] |
1137
|
|
|
ID for AFK channel |default| :data:`None` |
1138
|
|
|
afk_timeout : Optional[:class:`int`] |
1139
|
|
|
AFK timeout in seconds |default| :data:`None` |
1140
|
|
|
icon : Optional[:class:`str`] |
1141
|
|
|
base64 1024x1024 png/jpeg/gif image for the guild icon |
1142
|
|
|
(can be animated gif when the server |
1143
|
|
|
has the `ANIMATED_ICON` feature) |default| :data:`None` |
1144
|
|
|
owner_id : Optional[:class:`~pincer.utils.snowflake.Snowflake`] |
1145
|
|
|
User ID to transfer guild ownership to (must be owner) |default| :data:`None` |
1146
|
|
|
splash : Optional[:class:`str`] |
1147
|
|
|
base64 16:9 png/jpeg image for the guild splash (when the |
1148
|
|
|
server has the `INVITE_SPLASH` feature) |default| :data:`None` |
1149
|
|
|
discovery_splash : Optional[:class:`str`] |
1150
|
|
|
base64 16:9 png/jpeg image for the guild discovery splash |
1151
|
|
|
(when the server has the `DISCOVERABLE` feature) |default| :data:`None` |
1152
|
|
|
banner : Optional[:class:`str`] |
1153
|
|
|
base64 16:9 png/jpeg image for the guild banner (when the |
1154
|
|
|
server has the `BANNER` feature) |default| :data:`None` |
1155
|
|
|
system_channel_id : Optional[:class:`~pincer.utils.snowflake.Snowflake`] |
1156
|
|
|
The ID of the channel where guild notices such as welcome |
1157
|
|
|
messages and boost events are posted |default| :data:`None` |
1158
|
|
|
system_channel_flags : Optional[:class:`int`] |
1159
|
|
|
System channel flags |default| :data:`None` |
1160
|
|
|
rules_channel_id : Optional[:class:`~pincer.utils.snowflake.Snowflake`] |
1161
|
|
|
The ID of the channel where Community guilds display rules |
1162
|
|
|
and/or guidelines |default| :data:`None` |
1163
|
|
|
public_updates_channel_id : Optional[:class:`~pincer.utils.snowflake.Snowflake`] |
1164
|
|
|
The ID of the channel where admins and moderators of |
1165
|
|
|
Community guilds receive notices from Discord |default| :data:`None` |
1166
|
|
|
preferred_locale : Optional[:class:`str`] |
1167
|
|
|
The preferred locale of a Community guild used in server |
1168
|
|
|
discovery and notices from Discord; defaults to "en-US" |default| :data:`None` |
1169
|
|
|
features : Optional[List[:class:`GuildFeature`]] |
1170
|
|
|
Enabled guild features |default| :data:`None` |
1171
|
|
|
description : Optional[:class:`str`] |
1172
|
|
|
The description for the guild, if the guild is discoverable |default| :data:`None` |
1173
|
|
|
|
1174
|
|
|
Returns |
1175
|
|
|
------- |
1176
|
|
|
:class:`~pincer.objects.guild.Guild` |
1177
|
|
|
The modified guild object. |
1178
|
|
|
""" |
1179
|
|
|
... |
1180
|
|
|
|
1181
|
|
|
async def edit(self, **kwargs) -> Guild: |
|
|
|
|
1182
|
|
|
g = await self._http.patch(f"guilds/{self.id}", data=kwargs) |
1183
|
|
|
return Guild.from_dict(g) |
1184
|
|
|
|
1185
|
|
|
async def preview(self) -> GuildPreview: |
1186
|
|
|
"""|coro| |
1187
|
|
|
Previews the guild. |
1188
|
|
|
|
1189
|
|
|
Returns |
1190
|
|
|
------- |
1191
|
|
|
:class:`~pincer.objects.guild.guild.GuildPreview` |
1192
|
|
|
The guild preview object. |
1193
|
|
|
""" |
1194
|
|
|
data = await self._http.get(f"guilds/{self.id}/preview") |
1195
|
|
|
return GuildPreview.from_dict(data) |
1196
|
|
|
|
1197
|
|
|
async def delete(self): |
1198
|
|
|
"""|coro| |
1199
|
|
|
Deletes the guild. Returns `204 No Content` on success. |
1200
|
|
|
""" |
1201
|
|
|
await self._http.delete(f"guilds/{self.id}") |
1202
|
|
|
|
1203
|
|
|
async def prune_count( |
1204
|
|
|
self, days: Optional[int] = 7, include_roles: Optional[str] = None |
|
|
|
|
1205
|
|
|
) -> int: |
1206
|
|
|
"""|coro| |
1207
|
|
|
Returns the number of members that |
1208
|
|
|
would be removed in a prune operation. |
1209
|
|
|
Requires the ``KICK_MEMBERS`` permission. |
1210
|
|
|
|
1211
|
|
|
Parameters |
1212
|
|
|
---------- |
1213
|
|
|
days : Optional[:class:`int`] |
1214
|
|
|
Number of days to count prune for (1-30) |default| :data:`7` |
1215
|
|
|
include_roles : Optional[:class:`str`] |
1216
|
|
|
Comma-delimited array of Snowflakes; |
1217
|
|
|
role(s) to include |default| :data:`None` |
1218
|
|
|
|
1219
|
|
|
Returns |
1220
|
|
|
------- |
1221
|
|
|
:class:`int` |
1222
|
|
|
The number of members that would be removed. |
1223
|
|
|
""" |
1224
|
|
|
return await self._http.get( |
1225
|
|
|
f"guilds/{self.id}/prune", |
1226
|
|
|
params={"days": days, "include_roles": include_roles}, |
1227
|
|
|
)["pruned"] |
1228
|
|
|
|
1229
|
|
|
async def prune( |
1230
|
|
|
self, |
|
|
|
|
1231
|
|
|
days: Optional[int] = 7, |
|
|
|
|
1232
|
|
|
compute_prune_days: Optional[bool] = True, |
|
|
|
|
1233
|
|
|
include_roles: Optional[List[Snowflake]] = None, |
|
|
|
|
1234
|
|
|
reason: Optional[str] = None, |
|
|
|
|
1235
|
|
|
) -> int: |
1236
|
|
|
"""|coro| |
1237
|
|
|
Prunes members from the guild. Requires the ``KICK_MEMBERS`` permission. |
1238
|
|
|
|
1239
|
|
|
Parameters |
1240
|
|
|
|
1241
|
|
|
Parameters |
1242
|
|
|
---------- |
1243
|
|
|
days : Optional[:class:`int`] |
1244
|
|
|
Number of days to prune (1-30) |default| :data:`7` |
1245
|
|
|
compute_prune_days : Optional[:class:`bool`] |
1246
|
|
|
Whether ``pruned`` is returned, discouraged for large guilds |
1247
|
|
|
|default| :data:`True` |
1248
|
|
|
include_roles : Optional[List[:class:`~pincer.utils.snowflake.Snowflake`]] |
1249
|
|
|
role(s) to include |default| :data:`None` |
1250
|
|
|
reason : Optional[:class:`str`] |
1251
|
|
|
Reason for the prune |default| :data:`None` |
1252
|
|
|
|
1253
|
|
|
Returns |
1254
|
|
|
------- |
1255
|
|
|
:class:`int` |
1256
|
|
|
The number of members that were removed. |
1257
|
|
|
""" |
1258
|
|
|
return await self._http.post( |
1259
|
|
|
f"guilds/{self.id}/prune", |
1260
|
|
|
data={ |
1261
|
|
|
"days": days, |
1262
|
|
|
"compute_prune_days": compute_prune_days, |
1263
|
|
|
"include_roles": include_roles, |
1264
|
|
|
}, |
1265
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
1266
|
|
|
)["pruned"] |
1267
|
|
|
|
1268
|
|
|
def get_voice_regions(self) -> APIDataGen[VoiceRegion]: |
1269
|
|
|
"""|coro| |
1270
|
|
|
Returns an async generator of voice regions. |
1271
|
|
|
|
1272
|
|
|
Yields |
1273
|
|
|
------- |
1274
|
|
|
AsyncGenerator[:class:`~pincer.objects.voice.VoiceRegion`, :data:`None`] |
1275
|
|
|
An async generator of voice regions. |
1276
|
|
|
""" |
1277
|
|
|
|
1278
|
|
|
return APIDataGen( |
1279
|
|
|
VoiceRegion, self._http.get(f"guilds/{self.id}/regions") |
1280
|
|
|
) |
1281
|
|
|
|
1282
|
|
|
def get_invites(self) -> APIDataGen[Invite]: |
1283
|
|
|
"""|coro| |
1284
|
|
|
Returns an async generator of invites for the guild. |
1285
|
|
|
Requires the ``MANAGE_GUILD`` permission. |
1286
|
|
|
|
1287
|
|
|
Yields |
1288
|
|
|
------- |
1289
|
|
|
AsyncGenerator[:class:`~pincer.objects.invite.Invite`, :data:`None`] |
1290
|
|
|
An async generator of invites. |
1291
|
|
|
""" |
1292
|
|
|
|
1293
|
|
|
return APIDataGen(Invite, self._http.get(f"guilds/{self.id}/invites")) |
1294
|
|
|
|
1295
|
|
|
async def get_invite(self, code: str) -> Invite: |
1296
|
|
|
"""|coro| |
1297
|
|
|
Returns an Invite object for the given invite code. |
1298
|
|
|
|
1299
|
|
|
Parameters |
1300
|
|
|
---------- |
1301
|
|
|
code : :class:`str` |
1302
|
|
|
The invite code to get the invite for. |
1303
|
|
|
|
1304
|
|
|
Returns |
1305
|
|
|
------- |
1306
|
|
|
:class:`~pincer.objects.guild.invite.Invite` |
1307
|
|
|
The invite object. |
1308
|
|
|
""" |
1309
|
|
|
data = await self._http.get(f"invite/{code}") |
1310
|
|
|
return Invite.from_dict(data) |
1311
|
|
|
|
1312
|
|
|
def get_integrations(self) -> APIDataGen[Integration]: |
1313
|
|
|
"""|coro| |
1314
|
|
|
Returns an async generator of integrations for the guild. |
1315
|
|
|
Requires the ``MANAGE_GUILD`` permission. |
1316
|
|
|
|
1317
|
|
|
Yields |
1318
|
|
|
------- |
1319
|
|
|
AsyncGenerator[:class:`~pincer.objects.integration.Integration`, :data:`None`] |
1320
|
|
|
An async generator of integrations. |
1321
|
|
|
""" |
1322
|
|
|
|
1323
|
|
|
return APIDataGen( |
1324
|
|
|
Integration, self._http.get(f"guilds/{self.id}/integrations") |
1325
|
|
|
) |
1326
|
|
|
|
1327
|
|
|
async def delete_integration( |
1328
|
|
|
self, integration: Integration, reason: Optional[str] = None |
|
|
|
|
1329
|
|
|
): |
1330
|
|
|
"""|coro| |
1331
|
|
|
Deletes an integration. |
1332
|
|
|
Requires the ``MANAGE_GUILD`` permission. |
1333
|
|
|
|
1334
|
|
|
Parameters |
1335
|
|
|
---------- |
1336
|
|
|
integration : :class:`~pincer.objects.integration.Integration` |
1337
|
|
|
The integration to delete. |
1338
|
|
|
reason : Optional[:class:`str`] |
1339
|
|
|
Reason for the deletion |default| :data:`None` |
1340
|
|
|
""" |
1341
|
|
|
await self._http.delete( |
1342
|
|
|
f"guilds/{self.id}/integrations/{integration.id}", |
1343
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
1344
|
|
|
) |
1345
|
|
|
|
1346
|
|
|
async def delete_invite(self, code: str): |
1347
|
|
|
"""|coro| |
1348
|
|
|
Deletes an invite. |
1349
|
|
|
Requires the ``MANAGE_GUILD`` intent. |
1350
|
|
|
|
1351
|
|
|
Parameters |
1352
|
|
|
---------- |
1353
|
|
|
code : :class:`str` |
1354
|
|
|
The code of the invite to delete. |
1355
|
|
|
""" |
1356
|
|
|
await self._http.delete(f"guilds/{self.id}/invites/{code}") |
1357
|
|
|
|
1358
|
|
|
async def get_widget_settings(self) -> GuildWidget: |
1359
|
|
|
"""|coro| |
1360
|
|
|
Returns the guild widget settings. |
1361
|
|
|
Requires the ``MANAGE_GUILD`` permission. |
1362
|
|
|
|
1363
|
|
|
Returns |
1364
|
|
|
------- |
1365
|
|
|
:class:`~pincer.objects.guild.widget.GuildWidget` |
1366
|
|
|
The guild widget settings. |
1367
|
|
|
""" |
1368
|
|
|
return GuildWidget.from_dict( |
1369
|
|
|
await self._http.get(f"guilds/{self.id}/widget") |
1370
|
|
|
) |
1371
|
|
|
|
1372
|
|
|
async def modify_widget( |
1373
|
|
|
self, reason: Optional[str] = None, **kwargs |
|
|
|
|
1374
|
|
|
) -> GuildWidget: |
1375
|
|
|
"""|coro| |
1376
|
|
|
Modifies the guild widget for the guild. |
1377
|
|
|
Requires the ``MANAGE_GUILD`` permission. |
1378
|
|
|
|
1379
|
|
|
Parameters |
1380
|
|
|
---------- |
1381
|
|
|
reason : Optional[:class:`str`] |
1382
|
|
|
Reason for the modification |default| :data:`None` |
1383
|
|
|
\\*\\*kwargs |
1384
|
|
|
The widget settings to modify |
1385
|
|
|
|
1386
|
|
|
Returns |
1387
|
|
|
------- |
1388
|
|
|
:class:`~pincer.objects.guild.widget.GuildWidget` |
1389
|
|
|
The updated GuildWidget object |
1390
|
|
|
""" |
1391
|
|
|
data = await self._http.patch( |
1392
|
|
|
f"guilds/{self.id}/widget", |
1393
|
|
|
data=kwargs, |
1394
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
1395
|
|
|
) |
1396
|
|
|
return GuildWidget.from_dict(data) |
1397
|
|
|
|
1398
|
|
|
async def get_widget(self) -> Dict[str, JSONSerializable]: |
1399
|
|
|
"""|coro| |
1400
|
|
|
Returns the widget for the guild |
1401
|
|
|
""" |
1402
|
|
|
return await self._http.get(f"guilds/{self.id}/widget.json") |
1403
|
|
|
|
1404
|
|
|
@property |
1405
|
|
|
async def vanity_url(self) -> Invite: |
1406
|
|
|
"""|coro| |
1407
|
|
|
Returns the Vanity URL for the guild. |
1408
|
|
|
Requires the ``MANAGE_GUILD`` permission. |
1409
|
|
|
``code`` will be null if a vanity URL has not been set. |
1410
|
|
|
|
1411
|
|
|
Returns |
1412
|
|
|
------- |
1413
|
|
|
:class:`~pincer.objects.guild.invite.Invite` |
1414
|
|
|
The vanity url for the guild. |
1415
|
|
|
""" |
1416
|
|
|
data = await self._http.get(f"guilds/{self.id}/vanity-url") |
1417
|
|
|
return Invite.from_dict(data) |
1418
|
|
|
|
1419
|
|
|
async def get_widget_image( |
1420
|
|
|
self, style: Optional[str] = "shield" |
|
|
|
|
1421
|
|
|
) -> str: # TODO Replace str with ImageURL object |
|
|
|
|
1422
|
|
|
"""|coro| |
1423
|
|
|
Returns a PNG image widget for the guild. |
1424
|
|
|
Requires no permissions or authentication. |
1425
|
|
|
|
1426
|
|
|
Widget Style Options |
1427
|
|
|
------------------- |
1428
|
|
|
* [``shield``](https://discord.com/api/guilds/81384788765712384/widget.png?style=shield) |
1429
|
|
|
shield style widget with Discord icon and guild members online count |
1430
|
|
|
* [``banner1``](https://discord.com/api/guilds/81384788765712384/widget.png?style=banner1) |
1431
|
|
|
large image with guild icon, name and online count. |
1432
|
|
|
"POWERED BY DISCORD" as the footer of the widget |
1433
|
|
|
* [``banner2``](https://discord.com/api/guilds/81384788765712384/widget.png?style=banner2) |
1434
|
|
|
smaller widget style with guild icon, name and online count. |
1435
|
|
|
Split on the right with Discord logo |
1436
|
|
|
* [``banner3``](https://discord.com/api/guilds/81384788765712384/widget.png?style=banner3) |
1437
|
|
|
large image with guild icon, name and online count. |
1438
|
|
|
In the footer, Discord logo on the |
1439
|
|
|
left and "Chat Now" on the right |
1440
|
|
|
* [``banner4``](https://discord.com/api/guilds/81384788765712384/widget.png?style=banner4) |
1441
|
|
|
large Discord logo at the top of the widget. |
1442
|
|
|
Guild icon, name and online count in the middle portion |
1443
|
|
|
of the widget and a "JOIN MY SERVER" button at the bottom |
1444
|
|
|
|
1445
|
|
|
Parameters |
1446
|
|
|
---------- |
1447
|
|
|
style : Optional[:class:`str`] |
1448
|
|
|
Style of the widget image returned |default| :data:`"shield"` |
1449
|
|
|
|
1450
|
|
|
Returns |
1451
|
|
|
------- |
1452
|
|
|
:class:`str` |
1453
|
|
|
A PNG image of the guild widget. |
1454
|
|
|
""" |
1455
|
|
|
return await self._http.get(f"guilds/{self.id}/widget.png?{style=!s}") |
1456
|
|
|
|
1457
|
|
|
async def get_welcome_screen(self) -> WelcomeScreen: |
1458
|
|
|
"""Returns the welcome screen for the guild. |
1459
|
|
|
|
1460
|
|
|
Returns |
1461
|
|
|
------- |
1462
|
|
|
:class:`~pincer.objects.guild.welcome_screen.WelcomeScreen` |
1463
|
|
|
The welcome screen for the guild. |
1464
|
|
|
""" |
1465
|
|
|
data = await self._http.get(f"guilds/{self.id}/welcome-screen") |
1466
|
|
|
return WelcomeScreen.from_dict(data) |
1467
|
|
|
|
1468
|
|
|
async def modify_welcome_screen( |
1469
|
|
|
self, |
|
|
|
|
1470
|
|
|
enabled: Optional[bool] = None, |
|
|
|
|
1471
|
|
|
welcome_channels: Optional[List[WelcomeScreenChannel]] = None, |
|
|
|
|
1472
|
|
|
description: Optional[str] = None, |
|
|
|
|
1473
|
|
|
reason: Optional[str] = None, |
|
|
|
|
1474
|
|
|
) -> WelcomeScreen: |
1475
|
|
|
"""|coro| |
1476
|
|
|
Modifies the guild's Welcome Screen. |
1477
|
|
|
Requires the ``MANAGE_GUILD`` permission. |
1478
|
|
|
|
1479
|
|
|
Parameters |
1480
|
|
|
---------- |
1481
|
|
|
enabled : Optional[:class:`bool`] |
1482
|
|
|
Whether the welcome screen is enabled |default| :data:`None` |
1483
|
|
|
welcome_channels : Optional[List[:class:`~pincer.objects.guild.welcome_screen.WelcomeScreenChannel`]] |
|
|
|
|
1484
|
|
|
Channels linked in the welcome screen and |
1485
|
|
|
their display options |default| :data:`None` |
1486
|
|
|
description : Optional[:class:`str`] |
1487
|
|
|
The server description to show |
1488
|
|
|
in the welcome screen |default| :data:`None` |
1489
|
|
|
reason : Optional[:class:`str`] |
1490
|
|
|
Reason for the modification |default| :data:`None` |
1491
|
|
|
|
1492
|
|
|
Returns |
1493
|
|
|
------- |
1494
|
|
|
:class:`~pincer.objects.guild.welcome_screen.WelcomeScreen` |
1495
|
|
|
The updated WelcomeScreen object |
1496
|
|
|
""" |
1497
|
|
|
data = await self._http.patch( |
1498
|
|
|
f"guilds/{self.id}/welcome-screen", |
1499
|
|
|
data={ |
1500
|
|
|
"enabled": enabled, |
1501
|
|
|
"welcome_channels": welcome_channels, |
1502
|
|
|
"description": description, |
1503
|
|
|
}, |
1504
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
1505
|
|
|
) |
1506
|
|
|
return WelcomeScreen.from_dict(data) |
1507
|
|
|
|
1508
|
|
|
async def modify_current_user_voice_state( |
1509
|
|
|
self, |
|
|
|
|
1510
|
|
|
channel_id: Snowflake, |
|
|
|
|
1511
|
|
|
suppress: Optional[bool] = None, |
|
|
|
|
1512
|
|
|
request_to_speak_timestamp: Optional[Timestamp] = None, |
|
|
|
|
1513
|
|
|
): |
1514
|
|
|
"""|coro| |
1515
|
|
|
Updates the current user's voice state. |
1516
|
|
|
|
1517
|
|
|
There are currently several caveats for this endpoint: |
1518
|
|
|
* ``channel_id`` must currently point to a stage channel |
1519
|
|
|
* current user must already have joined ``channel_id`` |
1520
|
|
|
* You must have the ``MUTE_MEMBERS`` permission to |
1521
|
|
|
unsuppress yourself. You can always suppress yourself. |
1522
|
|
|
* You must have the ``REQUEST_TO_SPEAK`` permission to request |
1523
|
|
|
to speak. You can always clear your own request to speak. |
1524
|
|
|
* You are able to set ``request_to_speak_timestamp`` to any |
1525
|
|
|
present or future time. |
1526
|
|
|
|
1527
|
|
|
Parameters |
1528
|
|
|
---------- |
1529
|
|
|
channel_id : :class:`~pincer.utils.snowflake.Snowflake` |
1530
|
|
|
The ID of the channel the user is currently in |
1531
|
|
|
suppress : Optional[:class:`bool`] |
1532
|
|
|
Toggles the user's suppress state |default| :data:`None` |
1533
|
|
|
request_to_speak_timestamp : Optional[:class:`~pincer.utils.timestamp.Timestamp`] |
1534
|
|
|
Sets the user's request to speak |
1535
|
|
|
""" |
1536
|
|
|
await self._http.patch( |
1537
|
|
|
f"guilds/{self.id}/voice-states/@me", |
1538
|
|
|
data={ |
1539
|
|
|
"channel_id": channel_id, |
1540
|
|
|
"suppress": suppress, |
1541
|
|
|
"request_to_speak_timestamp": request_to_speak_timestamp, |
1542
|
|
|
}, |
1543
|
|
|
) |
1544
|
|
|
|
1545
|
|
|
async def modify_user_voice_state( |
1546
|
|
|
self, user: User, channel_id: Snowflake, suppress: Optional[bool] = None |
|
|
|
|
1547
|
|
|
): |
1548
|
|
|
"""|coro| |
1549
|
|
|
Updates another user's voice state. |
1550
|
|
|
|
1551
|
|
|
There are currently several caveats for this endpoint: |
1552
|
|
|
* ``channel_id`` must currently point to a stage channel |
1553
|
|
|
* User must already have joined ``channel_id`` |
1554
|
|
|
* You must have the ``MUTE_MEMBERS`` permission. |
1555
|
|
|
(Since suppression is the only thing that is available currently.) |
1556
|
|
|
* When unsuppressed, non-bot users will have their |
1557
|
|
|
``request_to_speak_timestamp`` set to the current time. |
1558
|
|
|
Bot users will not. |
1559
|
|
|
* When suppressed, the user will have their |
1560
|
|
|
``request_to_speak_timestamp`` removed. |
1561
|
|
|
|
1562
|
|
|
Parameters |
1563
|
|
|
---------- |
1564
|
|
|
user : :class:`~pincer.objects.guild.member.Member` |
1565
|
|
|
The user to update |
1566
|
|
|
channel_id : :class:`~pincer.utils.snowflake.Snowflake` |
1567
|
|
|
The ID of the channel the user is currently in |
1568
|
|
|
suppress : Optional[:class:`bool`] |
1569
|
|
|
Toggles the user's suppress state |default| :data:`None` |
1570
|
|
|
""" |
1571
|
|
|
await self._http.patch( |
1572
|
|
|
f"guilds/{self.id}/voice-states/{user.id}", |
1573
|
|
|
data={"channel_id": channel_id, "suppress": suppress}, |
1574
|
|
|
) |
1575
|
|
|
|
1576
|
|
|
async def get_audit_log(self) -> AuditLog: |
1577
|
|
|
"""|coro| |
1578
|
|
|
Returns an audit log object for the guild. |
1579
|
|
|
Requires the ``VIEW_AUDIT_LOG`` permission. |
1580
|
|
|
|
1581
|
|
|
Returns |
1582
|
|
|
------- |
1583
|
|
|
:class:`~pincer.objects.guild.audit_log.AuditLog` |
1584
|
|
|
The audit log object for the guild. |
1585
|
|
|
""" |
1586
|
|
|
return AuditLog.from_dict( |
1587
|
|
|
await self._http.get(f"guilds/{self.id}/audit-logs") |
1588
|
|
|
) |
1589
|
|
|
|
1590
|
|
|
def get_emojis(self) -> APIDataGen[Emoji]: |
1591
|
|
|
"""|coro| |
1592
|
|
|
Returns an async generator of the emojis in the guild. |
1593
|
|
|
|
1594
|
|
|
Yields |
1595
|
|
|
------ |
1596
|
|
|
:class:`~pincer.objects.guild.emoji.Emoji` |
1597
|
|
|
The emoji object. |
1598
|
|
|
""" |
1599
|
|
|
return APIDataGen(Emoji, self._http.get(f"guilds/{self.id}/emojis")) |
1600
|
|
|
|
1601
|
|
|
async def get_emoji(self, id: Snowflake) -> Emoji: |
|
|
|
|
1602
|
|
|
"""|coro| |
1603
|
|
|
Returns an emoji object for the given ID. |
1604
|
|
|
|
1605
|
|
|
Parameters |
1606
|
|
|
---------- |
1607
|
|
|
id : :class:`~pincer.utils.snowflake.Snowflake` |
1608
|
|
|
The ID of the emoji |
1609
|
|
|
|
1610
|
|
|
Returns |
1611
|
|
|
------- |
1612
|
|
|
:class:`~pincer.objects.guild.emoji.Emoji` |
1613
|
|
|
The emoji object. |
1614
|
|
|
""" |
1615
|
|
|
return Emoji.from_dict( |
1616
|
|
|
await self._http.get(f"guilds/{self.id}/emojis/{id}") |
1617
|
|
|
) |
1618
|
|
|
|
1619
|
|
|
async def create_emoji( |
1620
|
|
|
self, |
|
|
|
|
1621
|
|
|
*, |
|
|
|
|
1622
|
|
|
name: str, |
|
|
|
|
1623
|
|
|
image: File, |
|
|
|
|
1624
|
|
|
roles: Optional[List[Snowflake]] = None, |
|
|
|
|
1625
|
|
|
reason: Optional[str] = None, |
|
|
|
|
1626
|
|
|
) -> Emoji: |
1627
|
|
|
"""|coro| |
1628
|
|
|
Creates a new emoji for the guild. |
1629
|
|
|
Requires the ``MANAGE_EMOJIS_AND_STICKERS`` permission. |
1630
|
|
|
|
1631
|
|
|
Emojis and animated emojis have a maximum file size of 256kb. |
1632
|
|
|
Attempting to upload an emoji larger than this limit will fail. |
1633
|
|
|
|
1634
|
|
|
Parameters |
1635
|
|
|
---------- |
1636
|
|
|
name : :class:`str` |
1637
|
|
|
Name of the emoji |
1638
|
|
|
image : :class:`~pincer.objects.message.file.File` |
1639
|
|
|
The File for the 128x128 emoji image data |
1640
|
|
|
roles : Optional[List[:class:`~pincer.utils.snowflake.Snowflake`]] |
1641
|
|
|
Roles allowed to use this emoji |default| :data:`[]` |
1642
|
|
|
reason : Optional[:class:`str`] |
1643
|
|
|
The reason for creating the emoji |default| :data:`None` |
1644
|
|
|
|
1645
|
|
|
Returns |
1646
|
|
|
------- |
1647
|
|
|
:class:`~pincer.objects.guild.emoji.Emoji` |
1648
|
|
|
The newly created emoji object. |
1649
|
|
|
""" |
1650
|
|
|
roles = [] if roles is None else roles |
1651
|
|
|
|
1652
|
|
|
data = await self._http.post( |
1653
|
|
|
f"guilds/{self.id}/emojis", |
1654
|
|
|
data={"name": name, "image": image.uri, "roles": roles}, |
1655
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
1656
|
|
|
) |
1657
|
|
|
return Emoji.from_dict(data) |
1658
|
|
|
|
1659
|
|
|
async def edit_emoji( |
1660
|
|
|
self, |
|
|
|
|
1661
|
|
|
id: Snowflake, |
|
|
|
|
1662
|
|
|
*, |
|
|
|
|
1663
|
|
|
name: Optional[str] = None, |
|
|
|
|
1664
|
|
|
roles: Optional[List[Snowflake]] = None, |
|
|
|
|
1665
|
|
|
reason: Optional[str] = None, |
|
|
|
|
1666
|
|
|
) -> Emoji: |
1667
|
|
|
"""|coro| |
1668
|
|
|
Modifies the given emoji. |
1669
|
|
|
Requires the ``MANAGE_EMOJIS_AND_STICKERS`` permission. |
1670
|
|
|
|
1671
|
|
|
Parameters |
1672
|
|
|
---------- |
1673
|
|
|
id : :class:`~pincer.utils.snowflake.Snowflake` |
1674
|
|
|
The ID of the emoji |
1675
|
|
|
name : Optional[:class:`str`] |
1676
|
|
|
Name of the emoji |default| :data:`None` |
1677
|
|
|
roles : Optional[List[:class:`~pincer.utils.snowflake.Snowflake`]] |
1678
|
|
|
Roles allowed to use this emoji |default| :data:`None` |
1679
|
|
|
reason : Optional[:class:`str`] |
1680
|
|
|
The reason for editing the emoji |default| :data:`None` |
1681
|
|
|
|
1682
|
|
|
Returns |
1683
|
|
|
------- |
1684
|
|
|
:class:`~pincer.objects.guild.emoji.Emoji` |
1685
|
|
|
The modified emoji object. |
1686
|
|
|
""" |
1687
|
|
|
data = await self._http.patch( |
1688
|
|
|
f"guilds/{self.id}/emojis/{id}", |
1689
|
|
|
data={"name": name, "roles": roles}, |
1690
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
1691
|
|
|
) |
1692
|
|
|
return Emoji.from_dict(data) |
1693
|
|
|
|
1694
|
|
|
async def delete_emoji( |
1695
|
|
|
self, id: Snowflake, *, reason: Optional[str] = None |
|
|
|
|
1696
|
|
|
): |
1697
|
|
|
"""|coro| |
1698
|
|
|
Deletes the given emoji. |
1699
|
|
|
Requires the ``MANAGE_EMOJIS_AND_STICKERS`` permission. |
1700
|
|
|
|
1701
|
|
|
Parameters |
1702
|
|
|
---------- |
1703
|
|
|
id : :class:`~pincer.utils.snowflake.Snowflake` |
1704
|
|
|
The ID of the emoji |
1705
|
|
|
reason : Optional[:class:`str`] |
1706
|
|
|
The reason for deleting the emoji |default| :data:`None` |
1707
|
|
|
""" |
1708
|
|
|
await self._http.delete( |
1709
|
|
|
f"guilds/{self.id}/emojis/{id}", |
1710
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
1711
|
|
|
) |
1712
|
|
|
|
1713
|
|
|
def get_templates(self) -> APIDataGen[GuildTemplate]: |
1714
|
|
|
"""|coro| |
1715
|
|
|
Returns an async generator of the guild templates. |
1716
|
|
|
|
1717
|
|
|
Yields |
1718
|
|
|
------- |
1719
|
|
|
AsyncGenerator[:class:`~pincer.objects.guild.template.GuildTemplate`, :data:`None`] |
1720
|
|
|
The guild template object. |
1721
|
|
|
""" |
1722
|
|
|
|
1723
|
|
|
return APIDataGen( |
1724
|
|
|
GuildTemplate, self._http.get(f"guilds/{self.id}/templates") |
1725
|
|
|
) |
1726
|
|
|
|
1727
|
|
|
async def create_template( |
1728
|
|
|
self, name: str, description: Optional[str] = None |
|
|
|
|
1729
|
|
|
) -> GuildTemplate: |
1730
|
|
|
"""|coro| |
1731
|
|
|
Creates a new template for the guild. |
1732
|
|
|
Requires the ``MANAGE_GUILD`` permission. |
1733
|
|
|
|
1734
|
|
|
Parameters |
1735
|
|
|
---------- |
1736
|
|
|
name : :class:`str` |
1737
|
|
|
Name of the template (1-100 characters) |
1738
|
|
|
description : Optional[:class:`str`] |
1739
|
|
|
Description of the template |
1740
|
|
|
(0-120 characters) |default| :data:`None` |
1741
|
|
|
Returns |
1742
|
|
|
------- |
1743
|
|
|
:class:`~pincer.objects.guild.template.GuildTemplate` |
1744
|
|
|
The newly created template object. |
1745
|
|
|
""" |
1746
|
|
|
data = await self._http.post( |
1747
|
|
|
f"guilds/{self.id}/templates", |
1748
|
|
|
data={"name": name, "description": description}, |
1749
|
|
|
) |
1750
|
|
|
return GuildTemplate.from_dict(data) |
1751
|
|
|
|
1752
|
|
|
async def sync_template(self, template: GuildTemplate) -> GuildTemplate: |
1753
|
|
|
"""|coro| |
1754
|
|
|
Syncs the given template. |
1755
|
|
|
Requires the ``MANAGE_GUILD`` permission. |
1756
|
|
|
|
1757
|
|
|
Parameters |
1758
|
|
|
---------- |
1759
|
|
|
template : :class:`~pincer.objects.guild.template.GuildTemplate` |
1760
|
|
|
The template to sync |
1761
|
|
|
|
1762
|
|
|
Returns |
1763
|
|
|
------- |
1764
|
|
|
:class:`~pincer.objects.guild.template.GuildTemplate` |
1765
|
|
|
The synced template object. |
1766
|
|
|
""" |
1767
|
|
|
data = await self._http.put( |
1768
|
|
|
f"guilds/{self.id}/templates/{template.code}" |
1769
|
|
|
) |
1770
|
|
|
return GuildTemplate.from_dict(data) |
1771
|
|
|
|
1772
|
|
|
async def edit_template( |
1773
|
|
|
self, |
|
|
|
|
1774
|
|
|
template: GuildTemplate, |
|
|
|
|
1775
|
|
|
*, |
|
|
|
|
1776
|
|
|
name: Optional[str] = None, |
|
|
|
|
1777
|
|
|
description: Optional[str] = None, |
|
|
|
|
1778
|
|
|
) -> GuildTemplate: |
1779
|
|
|
"""|coro| |
1780
|
|
|
Modifies the template's metadata. |
1781
|
|
|
Requires the ``MANAGE_GUILD`` permission. |
1782
|
|
|
|
1783
|
|
|
Parameters |
1784
|
|
|
---------- |
1785
|
|
|
template : :class:`~pincer.objects.guild.template.GuildTemplate` |
1786
|
|
|
The template to edit |
1787
|
|
|
name : Optional[:class:`str`] |
1788
|
|
|
Name of the template (1-100 characters) |
1789
|
|
|
|default| :data:`None` |
1790
|
|
|
description : Optional[:class:`str`] |
1791
|
|
|
Description of the template (0-120 characters) |
1792
|
|
|
|default| :data:`None` |
1793
|
|
|
|
1794
|
|
|
Returns |
1795
|
|
|
------- |
1796
|
|
|
:class:`~pincer.objects.guild.template.GuildTemplate` |
1797
|
|
|
The edited template object. |
1798
|
|
|
""" |
1799
|
|
|
data = await self._http.patch( |
1800
|
|
|
f"guilds/{self.id}/templates/{template.code}", |
1801
|
|
|
data={"name": name, "description": description}, |
1802
|
|
|
) |
1803
|
|
|
return GuildTemplate.from_dict(data) |
1804
|
|
|
|
1805
|
|
|
async def delete_template(self, template: GuildTemplate) -> GuildTemplate: |
1806
|
|
|
"""|coro| |
1807
|
|
|
Deletes the given template. |
1808
|
|
|
Requires the ``MANAGE_GUILD`` permission. |
1809
|
|
|
|
1810
|
|
|
Parameters |
1811
|
|
|
---------- |
1812
|
|
|
template : :class:`~pincer.objects.guild.template.GuildTemplate` |
1813
|
|
|
The template to delete |
1814
|
|
|
|
1815
|
|
|
Returns |
1816
|
|
|
------- |
1817
|
|
|
:class:`~pincer.objects.guild.template.GuildTemplate` |
1818
|
|
|
The deleted template object. |
1819
|
|
|
""" |
1820
|
|
|
data = await self._http.delete( |
1821
|
|
|
f"guilds/{self.id}/templates/{template.code}" |
1822
|
|
|
) |
1823
|
|
|
return GuildTemplate.from_dict(data) |
1824
|
|
|
|
1825
|
|
|
def list_stickers(self) -> APIDataGen[Sticker]: |
1826
|
|
|
"""|coro| |
1827
|
|
|
Yields sticker objects for the current guild. |
1828
|
|
|
Includes ``user`` fields if the bot has the |
1829
|
|
|
``MANAGE_EMOJIS_AND_STICKERS`` permission. |
1830
|
|
|
|
1831
|
|
|
Yields |
1832
|
|
|
------ |
1833
|
|
|
:class:`~pincer.objects.message.sticker.Sticker` |
1834
|
|
|
a sticker for the current guild |
1835
|
|
|
""" |
1836
|
|
|
|
1837
|
|
|
return APIDataGen(Sticker, self._http.get(f"guild/{self.id}/stickers")) |
1838
|
|
|
|
1839
|
|
|
async def get_sticker(self, _id: Snowflake) -> Sticker: |
1840
|
|
|
"""|coro| |
1841
|
|
|
Returns a sticker object for the current guild and sticker IDs. |
1842
|
|
|
Includes the ``user`` field if the bot has the |
1843
|
|
|
``MANAGE_EMOJIS_AND_STICKERS`` permission. |
1844
|
|
|
|
1845
|
|
|
Parameters |
1846
|
|
|
---------- |
1847
|
|
|
_id : int |
1848
|
|
|
id of the sticker |
1849
|
|
|
|
1850
|
|
|
Returns |
1851
|
|
|
------- |
1852
|
|
|
:class:`~pincer.objects.message.sticker.Sticker` |
1853
|
|
|
the sticker requested |
1854
|
|
|
""" |
1855
|
|
|
sticker = await self._http.get(f"guilds/{self.id}/stickers/{_id}") |
1856
|
|
|
return Sticker.from_dict(sticker) |
1857
|
|
|
|
1858
|
|
|
async def create_sticker( |
|
|
|
|
1859
|
|
|
self, |
|
|
|
|
1860
|
|
|
name: str, |
|
|
|
|
1861
|
|
|
tags: str, |
|
|
|
|
1862
|
|
|
description: str, |
|
|
|
|
1863
|
|
|
file: File, |
|
|
|
|
1864
|
|
|
reason: Optional[str] = None, |
|
|
|
|
1865
|
|
|
) -> Sticker: |
1866
|
|
|
"""|coro| |
1867
|
|
|
Create a new sticker for the guild. |
1868
|
|
|
Requires the ``MANAGE_EMOJIS_AND_STICKERS permission``. |
1869
|
|
|
|
1870
|
|
|
Parameters |
1871
|
|
|
---------- |
1872
|
|
|
name : str |
1873
|
|
|
name of the sticker (2-30 characters) |
1874
|
|
|
tags : str |
1875
|
|
|
autocomplete/suggestion tags for the sticker (max 200 characters) |
1876
|
|
|
file : :class:`~pincer.objects.message.file.File` |
1877
|
|
|
the sticker file to upload, must be a PNG, APNG, or Lottie JSON file, max 500 KB |
1878
|
|
|
description : str |
1879
|
|
|
description of the sticker (empty or 2-100 characters) |default| :data:`""` |
1880
|
|
|
reason : Optional[:class:`str`] |default| :data:`None` |
1881
|
|
|
reason for creating the sticker |
1882
|
|
|
|
1883
|
|
|
Returns |
1884
|
|
|
------- |
1885
|
|
|
:class:`~pincer.objects.message.sticker.Sticker` |
1886
|
|
|
the newly created sticker |
1887
|
|
|
""" # noqa: E501 |
1888
|
|
|
|
1889
|
|
|
form = FormData() |
1890
|
|
|
form.add_field("name", name) |
1891
|
|
|
form.add_field("tags", tags) |
1892
|
|
|
form.add_field("description", description) |
1893
|
|
|
form.add_field("file", file.content, content_type=file.content_type) |
1894
|
|
|
|
1895
|
|
|
payload = form() |
1896
|
|
|
|
1897
|
|
|
sticker = await self._http.post( |
1898
|
|
|
f"guilds/{self.id}/stickers", |
1899
|
|
|
data=payload, |
1900
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
1901
|
|
|
content_type=payload.content_type, |
1902
|
|
|
) |
1903
|
|
|
|
1904
|
|
|
return Sticker.from_dict(sticker) |
1905
|
|
|
|
1906
|
|
|
async def delete_sticker(self, _id: Snowflake): |
1907
|
|
|
"""|coro| |
1908
|
|
|
Delete the given sticker. |
1909
|
|
|
Requires the ``MANAGE_EMOJIS_AND_STICKERS`` permission. |
1910
|
|
|
|
1911
|
|
|
Parameters |
1912
|
|
|
---------- |
1913
|
|
|
_id: Snowflake |
1914
|
|
|
id of the sticker |
1915
|
|
|
""" |
1916
|
|
|
await self._http.delete(f"guilds/{self.id}/stickers/{_id}") |
1917
|
|
|
|
1918
|
|
|
def get_webhooks(self) -> APIDataGen[Webhook]: |
1919
|
|
|
"""|coro| |
1920
|
|
|
Returns an async generator of the guild webhooks. |
1921
|
|
|
|
1922
|
|
|
Yields |
1923
|
|
|
------- |
1924
|
|
|
AsyncGenerator[:class:`~pincer.objects.guild.webhook.Webhook`, None] |
1925
|
|
|
The guild webhook object. |
1926
|
|
|
""" |
1927
|
|
|
|
1928
|
|
|
return APIDataGen(Webhook, self._http.get(f"guilds/{self.id}/webhooks")) |
1929
|
|
|
|
1930
|
|
|
def get_scheduled_events( |
1931
|
|
|
self, with_user_count: bool = False |
|
|
|
|
1932
|
|
|
) -> APIDataGen[ScheduledEvent]: |
1933
|
|
|
""" |
1934
|
|
|
Returns an async generator of the guild scheduled events. |
1935
|
|
|
|
1936
|
|
|
Parameters |
1937
|
|
|
---------- |
1938
|
|
|
with_user_count : :class:`bool` |
1939
|
|
|
Whether to include the user count in the scheduled event. |
1940
|
|
|
|
1941
|
|
|
Yields |
1942
|
|
|
------ |
1943
|
|
|
:class:`~pincer.objects.guild.scheduled_event.ScheduledEvent` |
1944
|
|
|
The scheduled event object. |
1945
|
|
|
""" |
1946
|
|
|
|
1947
|
|
|
return APIDataGen( |
1948
|
|
|
ScheduledEvent, |
1949
|
|
|
self._http.get( |
1950
|
|
|
f"guilds/{self.id}/scheduled-events", |
1951
|
|
|
param={"with_user_count": with_user_count}, |
1952
|
|
|
), |
1953
|
|
|
) |
1954
|
|
|
|
1955
|
|
|
async def create_scheduled_event( |
|
|
|
|
1956
|
|
|
self, |
|
|
|
|
1957
|
|
|
name: str, |
|
|
|
|
1958
|
|
|
privacy_level: int, |
|
|
|
|
1959
|
|
|
entity_type: int, |
|
|
|
|
1960
|
|
|
scheduled_start_time: datetime, |
|
|
|
|
1961
|
|
|
scheduled_end_time: Optional[datetime] = None, |
|
|
|
|
1962
|
|
|
entity_metadata: Optional[str] = None, |
|
|
|
|
1963
|
|
|
channel_id: Optional[int] = None, |
|
|
|
|
1964
|
|
|
description: Optional[str] = None, |
|
|
|
|
1965
|
|
|
reason: Optional[str] = None, |
|
|
|
|
1966
|
|
|
) -> ScheduledEvent: |
1967
|
|
|
""" |
1968
|
|
|
Create a new scheduled event for the guild. |
1969
|
|
|
|
1970
|
|
|
Parameters |
1971
|
|
|
---------- |
1972
|
|
|
name : :class:`str` |
1973
|
|
|
The name of the scheduled event. |
1974
|
|
|
privacy_level : :class:`int` |
1975
|
|
|
The privacy level of the scheduled event. |
1976
|
|
|
entity_type : :class:`int` |
1977
|
|
|
The type of entity to be scheduled. |
1978
|
|
|
scheduled_start_time : :class:`datetime` |
1979
|
|
|
The scheduled start time of the event. |
1980
|
|
|
scheduled_end_time : Optional[:class:`datetime`] |
1981
|
|
|
The scheduled end time of the event. |
1982
|
|
|
entity_metadata : Optional[:class:`str`] |
1983
|
|
|
The metadata of the entity to be scheduled. |
1984
|
|
|
channel_id : Optional[:class:`int`] |
1985
|
|
|
The channel id of the channel to be scheduled. |
1986
|
|
|
description : Optional[:class:`str`] |
1987
|
|
|
The description of the scheduled event. |
1988
|
|
|
reason : Optional[:class:`str`] |
1989
|
|
|
The reason for creating the scheduled event. |
1990
|
|
|
|
1991
|
|
|
Raises |
1992
|
|
|
------ |
1993
|
|
|
ValueError: |
1994
|
|
|
If an event is created in the past or if an event ends before it starts |
1995
|
|
|
|
1996
|
|
|
Returns |
1997
|
|
|
------- |
1998
|
|
|
:class:`~pincer.objects.guild.scheduled_event.ScheduledEvent` |
1999
|
|
|
The newly created scheduled event. |
2000
|
|
|
""" |
2001
|
|
|
if scheduled_start_time < datetime.now(): |
2002
|
|
|
raise ValueError("An event cannot be created in the past") |
2003
|
|
|
|
2004
|
|
|
if scheduled_end_time and scheduled_end_time < scheduled_start_time: |
2005
|
|
|
raise ValueError("An event cannot start before it ends") |
2006
|
|
|
|
2007
|
|
|
data = await self._http.post( |
2008
|
|
|
f"guilds/{self.id}/scheduled-events", |
2009
|
|
|
data={ |
2010
|
|
|
"name": name, |
2011
|
|
|
"privacy_level": privacy_level, |
2012
|
|
|
"entity_type": entity_type, |
2013
|
|
|
"scheduled_start_time": scheduled_start_time.isoformat(), |
2014
|
|
|
"scheduled_end_time": scheduled_end_time.isoformat() |
2015
|
|
|
if scheduled_end_time is not None |
|
|
|
|
2016
|
|
|
else None, |
|
|
|
|
2017
|
|
|
"entity_metadata": entity_metadata, |
2018
|
|
|
"channel_id": channel_id, |
2019
|
|
|
"description": description, |
2020
|
|
|
}, |
2021
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
2022
|
|
|
) |
2023
|
|
|
return ScheduledEvent.from_dict(data) |
2024
|
|
|
|
2025
|
|
|
async def get_scheduled_event( |
2026
|
|
|
self, _id: int, with_user_count: bool = False |
|
|
|
|
2027
|
|
|
) -> ScheduledEvent: |
2028
|
|
|
""" |
2029
|
|
|
Get a scheduled event by id. |
2030
|
|
|
|
2031
|
|
|
Parameters |
2032
|
|
|
---------- |
2033
|
|
|
_id : :class:`int` |
2034
|
|
|
The id of the scheduled event. |
2035
|
|
|
with_user_count : :class:`bool` |
2036
|
|
|
Whether to include the user count in the scheduled event. |
2037
|
|
|
|
2038
|
|
|
Returns |
2039
|
|
|
------- |
2040
|
|
|
:class:`~pincer.objects.guild.scheduled_event.ScheduledEvent` |
2041
|
|
|
The scheduled event object. |
2042
|
|
|
""" |
2043
|
|
|
data = await self._http.get( |
2044
|
|
|
f"guilds/{self.id}/scheduled-events/{_id}", |
2045
|
|
|
params={"with_user_count": with_user_count}, |
2046
|
|
|
) |
2047
|
|
|
return ScheduledEvent.from_dict(data) |
2048
|
|
|
|
2049
|
|
|
async def modify_scheduled_event( |
|
|
|
|
2050
|
|
|
self, |
|
|
|
|
2051
|
|
|
_id: int, |
|
|
|
|
2052
|
|
|
name: Optional[str] = None, |
|
|
|
|
2053
|
|
|
entity_type: Optional[int] = None, |
|
|
|
|
2054
|
|
|
privacy_level: Optional[int] = None, |
|
|
|
|
2055
|
|
|
scheduled_start_time: Optional[datetime] = None, |
|
|
|
|
2056
|
|
|
scheduled_end_time: Optional[datetime] = None, |
|
|
|
|
2057
|
|
|
entity_metadata: Optional[str] = None, |
|
|
|
|
2058
|
|
|
channel_id: Optional[int] = None, |
|
|
|
|
2059
|
|
|
description: Optional[str] = None, |
|
|
|
|
2060
|
|
|
status: Optional[int] = None, |
|
|
|
|
2061
|
|
|
reason: Optional[str] = None, |
|
|
|
|
2062
|
|
|
) -> ScheduledEvent: |
2063
|
|
|
""" |
2064
|
|
|
Modify a scheduled event. |
2065
|
|
|
|
2066
|
|
|
Parameters |
2067
|
|
|
---------- |
2068
|
|
|
_id : :class:`int` |
2069
|
|
|
The id of the scheduled event. |
2070
|
|
|
name : Optional[:class:`str`] |
2071
|
|
|
The name of the scheduled event. |
2072
|
|
|
entity_type : Optional[:class:`int`] |
2073
|
|
|
The type of entity to be scheduled. |
2074
|
|
|
privacy_level : Optional[:class:`int`] |
2075
|
|
|
The privacy level of the scheduled event. |
2076
|
|
|
scheduled_start_time : Optional[:class:`datetime`] |
2077
|
|
|
The scheduled start time of the event. |
2078
|
|
|
scheduled_end_time : Optional[:class:`datetime`] |
2079
|
|
|
The scheduled end time of the event. |
2080
|
|
|
entity_metadata : Optional[:class:`str`] |
2081
|
|
|
The metadata of the entity to be scheduled. |
2082
|
|
|
channel_id : Optional[:class:`int`] |
2083
|
|
|
The channel id of the channel to be scheduled. |
2084
|
|
|
description : Optional[:class:`str`] |
2085
|
|
|
The description of the scheduled event. |
2086
|
|
|
status : Optional[:class:`int`] |
2087
|
|
|
The status of the scheduled event. |
2088
|
|
|
reason : Optional[:class:`str`] |
2089
|
|
|
The reason for modifying the scheduled event. |
2090
|
|
|
|
2091
|
|
|
Raises |
2092
|
|
|
------ |
2093
|
|
|
:class:`ValueError` |
2094
|
|
|
If the scheduled event is in the past, |
2095
|
|
|
or if the scheduled end time is before the scheduled start time. |
2096
|
|
|
|
2097
|
|
|
Returns |
2098
|
|
|
------- |
2099
|
|
|
:class:`~pincer.objects.guild.scheduled_event.ScheduledEvent` |
2100
|
|
|
The scheduled event object. |
2101
|
|
|
""" |
2102
|
|
|
if scheduled_start_time: |
2103
|
|
|
if scheduled_start_time < datetime.now(): |
2104
|
|
|
raise ValueError("An event cannot be created in the past") |
2105
|
|
|
|
2106
|
|
|
if scheduled_end_time and scheduled_end_time < scheduled_start_time: |
2107
|
|
|
raise ValueError("An event cannot start before it ends") |
2108
|
|
|
|
2109
|
|
|
kwargs: Dict[str, str] = remove_none( |
2110
|
|
|
{ |
2111
|
|
|
"name": name, |
2112
|
|
|
"privacy_level": privacy_level, |
2113
|
|
|
"entity_type": entity_type, |
2114
|
|
|
"scheduled_start_time": scheduled_start_time.isoformat() |
2115
|
|
|
if scheduled_start_time is not None |
|
|
|
|
2116
|
|
|
else None, |
|
|
|
|
2117
|
|
|
"scheduled_end_time": scheduled_end_time.isoformat() |
2118
|
|
|
if scheduled_end_time is not None |
|
|
|
|
2119
|
|
|
else None, |
|
|
|
|
2120
|
|
|
"entity_metadata": entity_metadata, |
2121
|
|
|
"channel_id": channel_id, |
2122
|
|
|
"description": description, |
2123
|
|
|
"status": status, |
2124
|
|
|
} |
2125
|
|
|
) |
2126
|
|
|
|
2127
|
|
|
data = await self._http.patch( |
2128
|
|
|
f"guilds/{self.id}/scheduled-events/{_id}", |
2129
|
|
|
data=kwargs, |
2130
|
|
|
headers={"X-Audit-Log-Reason": reason}, |
2131
|
|
|
) |
2132
|
|
|
return ScheduledEvent.from_dict(data) |
2133
|
|
|
|
2134
|
|
|
async def delete_scheduled_event(self, _id: int): |
2135
|
|
|
""" |
2136
|
|
|
Delete a scheduled event. |
2137
|
|
|
|
2138
|
|
|
Parameters |
2139
|
|
|
---------- |
2140
|
|
|
_id : :class:`int` |
2141
|
|
|
The id of the scheduled event. |
2142
|
|
|
""" |
2143
|
|
|
await self._http.delete(f"guilds/{self.id}/scheduled-events/{_id}") |
2144
|
|
|
|
2145
|
|
|
def get_guild_scheduled_event_users( |
2146
|
|
|
self, |
|
|
|
|
2147
|
|
|
_id: int, |
|
|
|
|
2148
|
|
|
limit: int = 100, |
|
|
|
|
2149
|
|
|
with_member: bool = False, |
|
|
|
|
2150
|
|
|
before: Optional[int] = None, |
|
|
|
|
2151
|
|
|
after: Optional[int] = None, |
|
|
|
|
2152
|
|
|
) -> APIDataGen[GuildScheduledEventUser]: |
2153
|
|
|
""" |
2154
|
|
|
Get the users of a scheduled event. |
2155
|
|
|
|
2156
|
|
|
Parameters |
2157
|
|
|
---------- |
2158
|
|
|
_id : :class:`int` |
2159
|
|
|
The id of the scheduled event. |
2160
|
|
|
limit : :class:`int` |
2161
|
|
|
The number of users to retrieve. |
2162
|
|
|
with_member : :class:`bool` |
2163
|
|
|
Whether to include the member object in the scheduled event user. |
2164
|
|
|
before : Optional[:class:`int`] |
2165
|
|
|
consider only users before given user id |
2166
|
|
|
after : Optional[:class:`int`] |
2167
|
|
|
consider only users after given user id |
2168
|
|
|
|
2169
|
|
|
Yields |
2170
|
|
|
------ |
2171
|
|
|
:class:`~pincer.objects.guild.scheduled_event.GuildScheduledEventUser` |
2172
|
|
|
The scheduled event user object. |
2173
|
|
|
""" |
2174
|
|
|
params = remove_none( |
2175
|
|
|
{ |
2176
|
|
|
"limit": limit, |
2177
|
|
|
"with_member": with_member, |
2178
|
|
|
"before": before, |
2179
|
|
|
"after": after, |
2180
|
|
|
} |
2181
|
|
|
) |
2182
|
|
|
|
2183
|
|
|
return APIDataGen( |
2184
|
|
|
GuildScheduledEventUser, |
2185
|
|
|
self._http.get( |
2186
|
|
|
f"guilds/{self.id}/scheduled-events/{_id}/users", |
2187
|
|
|
params=params, |
2188
|
|
|
), |
2189
|
|
|
) |
2190
|
|
|
|
2191
|
|
|
@classmethod |
2192
|
|
|
def from_dict(cls, data) -> Guild: |
2193
|
|
|
""" |
2194
|
|
|
Parameters |
2195
|
|
|
---------- |
2196
|
|
|
data : :class:`Dict` |
2197
|
|
|
Guild data received from the discord API. |
2198
|
|
|
Returns |
2199
|
|
|
------- |
2200
|
|
|
:class:`~pincer.objects.guild.guild.Guild` |
2201
|
|
|
The new guild object. |
2202
|
|
|
Raises |
2203
|
|
|
------ |
2204
|
|
|
:class:`~pincer.exceptions.UnavailableGuildError` |
2205
|
|
|
The guild is unavailable due to a discord outage. |
2206
|
|
|
""" |
2207
|
|
|
if data.get("unavailable", False): |
2208
|
|
|
raise UnavailableGuildError( |
2209
|
|
|
f"Guild \"{data['id']}\" is unavailable due to a discord" |
2210
|
|
|
" outage." |
2211
|
|
|
) |
2212
|
|
|
|
2213
|
|
|
return super().from_dict(data) |
2214
|
|
|
|
2215
|
|
|
|
2216
|
|
|
@dataclass(repr=False) |
2217
|
|
|
class UnavailableGuild(APIObject): |
|
|
|
|
2218
|
|
|
id: Snowflake |
2219
|
|
|
unavailable: bool = True |
2220
|
|
|
|