Passed
Pull Request — main (#292)
by
unknown
01:55
created

pincer.objects.guild.guild.Guild.delete_sticker()   A

Complexity

Conditions 1

Size

Total Lines 11
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 11
rs 10
c 0
b 0
f 0
cc 1
nop 2
1
# Copyright Pincer 2021-Present
0 ignored issues
show
introduced by
Missing module docstring
Loading history...
coding-style introduced by
Too many lines in module (1691/1000)
Loading history...
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 enum import IntEnum
8
from typing import AsyncGenerator, overload, TYPE_CHECKING, Generator
9
10
from .invite import Invite
11
from .channel import Channel
12
from ..message.emoji import Emoji
13
from ..message.file import File
14
from ...exceptions import UnavailableGuildError
15
from ...utils.api_object import APIObject
16
from ...utils.conversion import construct_client_dict, remove_none
17
from ...utils.types import MISSING
18
19
20
if TYPE_CHECKING:
21
    from typing import Any, Dict, List, Optional, Union
22
23
    from .audit_log import AuditLog
24
    from .ban import Ban
25
    from .member import GuildMember
26
    from .features import GuildFeature
27
    from .role import Role
28
    from .stage import StageInstance
29
    from .template import GuildTemplate
30
    from .welcome_screen import WelcomeScreen, WelcomeScreenChannel
31
    from .widget import GuildWidget
32
    from .webhook import Webhook
33
    from ..user.user import User
34
    from ..user.integration import Integration
35
    from ..voice.region import VoiceRegion
36
    from ..events.presence import PresenceUpdateEvent
37
    from ..message.emoji import Emoji
0 ignored issues
show
Unused Code introduced by
The import Emoji was already done on line 12. You should be able to
remove this line.
Loading history...
38
    from ..message.sticker import Sticker, StickerPack
39
    from ..user.voice_state import VoiceState
40
    from ...client import Client
41
    from ...utils.timestamp import Timestamp
42
    from ...utils.types import APINullable, JSONSerializable
43
    from ...utils.snowflake import Snowflake
44
45
46
class PremiumTier(IntEnum):
47
    """Represents the boost tier of a guild.
48
    Attributes
49
    ----------
50
    NONE:
51
        Guild has not unlocked any Server Boost perks.
52
    TIER_1:
53
        Guild has unlocked Server Boost level 1 perks.
54
    TIER_2:
55
        Guild has unlocked Server Boost level 2 perks.
56
    TIER_3:
57
        Guild has unlocked Server Boost level 3 perks.
58
    """
59
60
    NONE = 0
61
    TIER_1 = 1
62
    TIER_2 = 2
63
    TIER_3 = 3
64
65
66
class GuildNSFWLevel(IntEnum):
67
    """Represents the NSFW level of a guild.
68
    Attributes
69
    ----------
70
    DEFAULT:
71
        Default NSFW level.
72
    EXPLICIT:
73
        Explicit NSFW level.
74
    SAFE:
75
        SAFE NSFW level.
76
    AGE_RESTRICTED:
77
        Age restricted NSFW level.
78
    """
79
80
    DEFAULT = 0
81
    EXPLICIT = 1
82
    SAFE = 2
83
    AGE_RESTRICTED = 3
84
85
86
class ExplicitContentFilterLevel(IntEnum):
87
    """Represents the filter content level of a guild.
88
    Attributes
89
    ----------
90
    DISABLED:
91
        Media content will not be scanned.
92
    MEMBERS_WITHOUT_ROLES:
93
        Media content sent by members without roles will be scanned.
94
    ALL_MEMBERS:
95
        Media content sent by all members will be scanned.
96
    """
97
98
    DISABLED = 0
99
    MEMBERS_WITHOUT_ROLES = 1
100
    ALL_MEMBERS = 2
101
102
103
class MFALevel(IntEnum):
104
    """Represents the multi factor authentication level of a guild.
105
    Attributes
106
    ----------
107
    NONE:
108
        Guild has no MFA/2FA requirement for moderation actions.
109
    ELEVATED:
110
        Guild has a 2FA requirement for moderation actions
111
    """
112
113
    NONE = 0
114
    ELEVATED = 1
115
116
117
class VerificationLevel(IntEnum):
118
    """Represents the verification level of a guild.
119
    Attributes
120
    ----------
121
    NONE:
122
        Unrestricted.
123
    LOW:
124
        Must have verified email on account.
125
    MEDIUM:
126
        Must be registered on Discord for longer than 5 minutes.
127
    HIGH:
128
        Must be a member of the server for longer than 10 minutes.
129
    VERY_HIGH:
130
        Must have a verified phone number.
131
    """
132
133
    NONE = 0
134
    LOW = 1
135
    MEDIUM = 2
136
    HIGH = 3
137
    VERY_HIGH = 4
138
139
140
class DefaultMessageNotificationLevel(IntEnum):
141
    """Represents the default message notification level of a guild.
142
    Attributes
143
    ----------
144
    ALL_MESSAGES:
145
        Members will receive notifications for all messages by default.
146
    ONLY_MENTIONS:
147
        Members will receive notifications only for messages that @mention them by default.
148
    """
149
150
    # noqa: E501
151
    ALL_MESSAGES = 0
152
    ONLY_MENTIONS = 1
153
154
155
class SystemChannelFlags(IntEnum):
156
    """Represents the system channel flags of a guild.
157
    Attributes
158
    ----------
159
    SUPPRESS_JOIN_NOTIFICATIONS:
160
        Suppress member join notifications.
161
    SUPPRESS_PREMIUM_SUBSCRIPTIONS:
162
        Suppress server boost notifications.
163
    SUPPRESS_GUILD_REMINDER_NOTIFICATIONS:
164
        Suppress server setup tips.
165
    SUPPRESS_JOIN_NOTIFICATION_REPLIES:
166
        Hide member join sticker reply buttons
167
    """
168
169
    SUPPRESS_JOIN_NOTIFICATIONS = 1 << 0
170
    SUPPRESS_PREMIUM_SUBSCRIPTIONS = 1 << 1
171
    SUPPRESS_GUILD_REMINDER_NOTIFICATIONS = 1 << 2
172
    SUPPRESS_JOIN_NOTIFICATION_REPLIES = 1 << 3
173
174
175
176
@dataclass(repr=False)
177
class GuildPreview(APIObject):
0 ignored issues
show
best-practice introduced by
Too many instance attributes (10/7)
Loading history...
178
    """Represents a guild preview.
179
    Attributes
180
    ----------
181
    id: :class:`Snowflake`
182
        The guild ID.
183
    name: :class:`str`
184
        The guild name.
185
    icon: :class:`str`
186
        The guild icon hash.
187
    splash: :class:`str`
188
        The guild splash hash.
189
    discovery_splash: :class:`str`
190
        The guild discovery splash hash.
191
    emojis: :class:`List[Emoji]`
192
        The guild emojis.
193
    features: :class:`List[GuildFeature]`
194
        The guild features.
195
    approximate_member_count: :class:`int`
196
        The approximate member count.
197
    approximate_presence_count: :class:`int`
198
        The approximate number of online members in this guild
199
    description: :class:`str`
200
        The guild description.
201
    """
202
203
    id: Snowflake
204
    name: str
205
    emojis: List[Emoji]
206
    features: List[GuildFeature]
207
    approximate_member_count: int
208
    approximate_presence_count: int
209
210
    icon: APINullable[str] = MISSING
211
    splash: APINullable[str] = MISSING
212
    discovery_splash: APINullable[str] = MISSING
213
    description: APINullable[str] = MISSING
214
215
216
@dataclass(repr=False)
217
class Guild(APIObject):
0 ignored issues
show
best-practice introduced by
Too many instance attributes (59/7)
Loading history...
best-practice introduced by
Too many public methods (49/20)
Loading history...
218
    """Represents a Discord guild/server in which your client resides.
219
    Attributes
220
    ----------
221
    afk_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
222
        Id of afk channel
223
    afk_timeout: :class:`int`
224
        Afk timeout in seconds
225
    application_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
226
        Application id of the guild creator if it is bot-created
227
    banner: Optional[:class:`str`]
228
        Banner hash
229
    default_message_notifications: :class:`~pincer.objects.guild.guild.DefaultMessageNotificationLevel`
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (103/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
230
        Default message notifications level
231
    description: Optional[:class:`str`]
232
        The description of a Community guild
233
    discovery_splash: Optional[:class:`str`]
234
        Discovery splash hash;
235
        only present for guilds with the "DISCOVERABLE" feature
236
    emojis: List[:class:`~pincer.objects.message.emoji.Emoji`]
237
        Custom guild emojis
238
    explicit_content_filter: :class:`~pincer.objects.guild.guild.ExplicitContentFilterLevel`
239
        Explicit content filter level
240
    features: List[:class:`~pincer.objects.guild.features.GuildFeature`]
241
        Enabled guild features
242
    id: :class:`~pincer.utils.snowflake.Snowflake`
243
        Guild id
244
    icon: Optional[:class:`str`]
245
        Icon hash
246
    mfa_level: :class:`~pincer.objects.guild.guild.MFALevel`
247
        Required MFA level for the guild
248
    name: :class:`str`
249
        Guild name (2-100 characters, excluding trailing and leading
250
        whitespace)
251
    nsfw_level: :class:`~pincer.objects.guild.guild.NSFWLevel`
252
        Guild NSFW level
253
    owner_id: :class:`~pincer.utils.snowflake.Snowflake`
254
        Id of owner
255
    preferred_locale: :class:`str`
256
        The preferred locale of a Community guild;
257
        used in server discovery and notices from Discord;
258
        defaults to "en-US"
259
    premium_tier: :class:`~pincer.objects.guild.guild.PremiumTier`
260
        Premium tier (Server Boost level)
261
    public_updates_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
262
        The id of the channel where admins
263
        and moderators of Community guilds receive notices from Discord
264
    roles: List[:class:`~pincer.objects.guild.role.Role`]
265
        Roles in the guild
266
    rules_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
267
        The id of the channel where Community guilds can display rules
268
        and/or guidelines
269
    splash: Optional[:class:`str`]
270
        Splash hash
271
    system_channel_flags: :class:`~pincer.objects.guild.guild.SystemChannelFlags`
272
        System channel flags
273
    system_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
274
        The id of the channel where guild notices
275
        such as welcome messages and boost events are posted
276
    vanity_url_code: Optional[:class:`str`]
277
        The vanity url code for the guild
278
    verification_level: :class:`~pincer.objects.guild.guild.VerificationLevel`
279
        Verification level required for the guild
280
    approximate_member_count: APINullable[:class:`int`]
281
        Approximate number of members in this guild, returned from the
282
        `GET /guilds/<id>` endpoint when with_counts is true
283
    approximate_presence_count: APINullable[:class:`int`]
284
        Approximate number of non-offline members in this guild,
285
        returned from the `GET /guilds/<id>`
286
        endpoint when with_counts is true
287
    channels: APINullable[List[:class:`~pincer.objects.guild.channel.Channel`]]
288
        Channels in the guild
289
    icon_hash: APINullable[Optional[:class:`str`]]
290
        Icon hash, returned when in the template object
291
    joined_at: APINullable[:class:`~pincer.utils.timestamp.Timestamp`]
292
        When this guild was joined at
293
    large: APINullable[:class:`bool`]
294
        True if this is considered a large guild
295
    max_members: APINullable[:class:`int`]
296
        The maximum number of members for the guild
297
    max_presences: APINullable[Optional[:class:`int`]]
298
        The maximum number of presences for the guild
299
        (null is always returned, apart from the largest of guilds)
300
    max_video_channel_users: APINullable[:class:`int`]
301
        The maximum amount of users in a video channel
302
    members: APINullable[List[:class:`~pincer.objects.guild.member.GuildMember`]]
303
        Users in the guild
304
    member_count: APINullable[:class:`bool`]
305
        Total number of members in this guild
306
    nsfw: APINullable[:class:`bool`]
307
        Boolean if the server is NSFW
308
    owner: APINullable[:class:`bool`]
309
        True if the user is the owner of the guild
310
    permissions: APINullable[:class:`str`]
311
        Total permissions for the user in the guild
312
        (excludes overwrites)
313
    premium_subscription_count: APINullable[:class:`int`]
314
        The number of boosts this guild currently has
315
    presences: APINullable[List[:class:`~pincer.objects.events.presence.PresenceUpdateEvent`]]
316
        Presences of the members in the guild,
317
        will only include non-offline members if the size is greater
318
        than large threshold
319
    stage_instances: APINullable[List[:class:`~pincer.objects.guild.stage.StageInstance`]]
320
        Stage instances in the guild
321
    stickers: Optional[List[:class:`~pincer.objects.message.sticker.Sticker`]]
322
        Custom guild stickers
323
    region: APINullable[Optional[:class:`str`]]
324
        Voice region id for the guild (deprecated)
325
    threads: APINullable[List[:class:`~pincer.objects.guild.channel.Channel`]]
326
        All active threads in the guild that current user
327
        has permission to view
328
    unavailable: APINullable[:class:`bool`]
329
        True if this guild is unavailable due to an outage
330
    voice_states: APINullable[List[:class:`~pincer.objects.user.voice_state.VoiceState`]]
331
        States of members currently in voice channels;
332
        lacks the guild_id key
333
    widget_enabled: APINullable[:class:`bool`]
334
        True if the server widget is enabled
335
    widget_channel_id: APINullable[Optional[:class:`~pincer.utils.snowflake.Snowflake`]]
336
        The channel id that the widget will generate an invite to,
337
        or null if set to no invite
338
    welcome_screen: APINullable[:class:`~pincer.objects.guild.welcome_screen.WelcomeScreen`]
339
        The welcome screen of a Community guild, shown to new members,
340
        returned in an Invite's guild object
341
    """
342
343
    # noqa: E501
344
    features: List[GuildFeature]
345
    id: Snowflake
346
    name: str
347
    nsfw_level: GuildNSFWLevel
348
    verification_level: VerificationLevel
349
350
    # Guild invites missing
351
    system_channel_flags: APINullable[SystemChannelFlags] = MISSING
352
    explicit_content_filter: APINullable[ExplicitContentFilterLevel] = MISSING
353
    premium_tier: APINullable[PremiumTier] = MISSING
354
    default_message_notifications: APINullable[DefaultMessageNotificationLevel] = MISSING
355
    mfa_level: APINullable[MFALevel] = MISSING
356
    owner_id: APINullable[Snowflake] = MISSING
357
    afk_timeout: APINullable[int] = MISSING
358
    emojis: APINullable[List[Emoji]] = MISSING
359
    preferred_locale: APINullable[str] = MISSING
360
    roles: APINullable[List[Role]] = MISSING
361
362
    guild_scheduled_events: APINullable[List] = MISSING
363
    lazy: APINullable[bool] = MISSING
364
    premium_progress_bar_enabled: APINullable[bool] = MISSING
365
    guild_hashes: APINullable[Dict] = MISSING
366
    afk_channel_id: APINullable[Snowflake] = MISSING
367
    application_id: APINullable[Snowflake] = MISSING
368
    embedded_activities: APINullable[List] = MISSING
369
    banner: APINullable[str] = MISSING
370
    description: APINullable[str] = MISSING
371
    discovery_splash: APINullable[str] = MISSING
372
    icon: APINullable[str] = MISSING
373
    public_updates_channel_id: APINullable[Snowflake] = MISSING
374
    rules_channel_id: APINullable[Snowflake] = MISSING
375
    splash: APINullable[str] = MISSING
376
    system_channel_id: APINullable[Snowflake] = MISSING
377
    vanity_url_code: APINullable[str] = MISSING
378
379
    application_command_counts: APINullable[Dict] = MISSING
380
    application_command_count: APINullable[int] = MISSING
381
    approximate_member_count: APINullable[int] = MISSING
382
    approximate_presence_count: APINullable[int] = MISSING
383
    channels: APINullable[List[Channel]] = field(default_factory=list)
384
    # TODO: Add type when type is known
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
385
    hub_type: APINullable[Any] = MISSING
386
    icon_hash: APINullable[Optional[str]] = MISSING
387
    joined_at: APINullable[Timestamp] = MISSING
388
    large: APINullable[bool] = MISSING
389
    max_members: APINullable[int] = MISSING
390
    max_presences: APINullable[Optional[int]] = MISSING
391
    max_video_channel_users: APINullable[int] = MISSING
392
    members: APINullable[List[GuildMember]] = MISSING
393
    member_count: APINullable[bool] = MISSING
394
    nsfw: APINullable[bool] = MISSING
395
    # Note: This is missing from discord's docs but in the api
396
    owner: APINullable[bool] = MISSING
397
    permissions: APINullable[str] = MISSING
398
    premium_subscription_count: APINullable[int] = MISSING
399
    presences: APINullable[List[PresenceUpdateEvent]] = MISSING
400
    stage_instances: APINullable[List[StageInstance]] = MISSING
401
    stickers: APINullable[List[Sticker]] = MISSING
402
    region: APINullable[Optional[str]] = MISSING
403
    threads: APINullable[List[Channel]] = MISSING
404
    # Guilds are considered available unless otherwise specified
405
    unavailable: APINullable[bool] = False
406
    voice_states: APINullable[List[VoiceState]] = MISSING
407
    widget_enabled: APINullable[bool] = MISSING
408
    widget_channel_id: APINullable[Optional[Snowflake]] = MISSING
409
    welcome_screen: APINullable[WelcomeScreen] = MISSING
410
411
    @classmethod
412
    async def from_id(cls, client: Client, _id: Union[int, Snowflake]) -> Guild:
413
        """
414
        Parameters
415
        ----------
416
        client : `~pincer.Client`
417
            Client object to use the http gateway from.
418
        _id : :class: `pincer.utils.snowflake.Snowflake`
419
            Guild ID.
420
        Returns
421
        -------
422
        :class: `~pincer.objects.guild.guild.Guild`
423
            The new guild object.
424
        """
425
        data = await client.http.get(f"/guilds/{_id}")
426
        channel_data = await client.http.get(f"/guilds/{_id}/channels")
427
428
        data["channels"]: List[Channel] = [
429
            Channel.from_dict(construct_client_dict(client, i))
430
            for i in (channel_data or [])
431
        ]
432
433
        return Guild.from_dict(construct_client_dict(client, data))
434
435
    async def get_member(self, _id: int) -> GuildMember:
436
        """|coro|
437
        Fetches a GuildMember from its identifier
438
439
        Parameters
440
        ----------
441
        _id: int
442
            The id of the guild member which should be fetched from the Discord
443
            gateway.
444
        Returns
445
        -------
446
        :class:`~pincer.objects.guild.member.GuildMember`
447
            A GuildMember object.
448
        """
449
        return await GuildMember.from_id(self._client, self.id, _id)
450
451
    @overload
452
    async def modify_member(
453
            self,
454
            *,
455
            _id: int,
456
            nick: Optional[str] = None,
457
            roles: Optional[List[Snowflake]] = None,
458
            mute: Optional[bool] = None,
459
            deaf: Optional[bool] = None,
460
            channel_id: Optional[Snowflake] = None,
461
    ) -> GuildMember:
462
        """|coro|
463
        Modifies a member in the guild from its identifier and based on the
464
        keyword arguments provided.
465
        Parameters
466
        ----------
467
        _id : int
468
            Id of the member to modify
469
        nick : Optional[:class:`str`]
470
            New nickname for the member |default| :data:`None`
471
        roles : Optional[List[:class:`~pincer.utils.snowflake.Snowflake]]
472
            New roles for the member |default| :data:`None`
473
        mute : Optional[:class:`bool`]
474
            Whether the member is muted |default| :data:`None`
475
        deaf : Optional[:class:`bool`]
476
            Whether the member is deafened |default| :data:`None`
477
        channel_id : Optional[:class:`~pincer.utils.snowflake.Snowflake]
478
            Voice channel id to move to |default| :data:`None`
479
        Returns
480
        -------
481
        :class:`~pincer.objects.guild.member.GuildMember`
482
            The new member object.
483
        """
484
        ...
485
486
    async def modify_member(self, _id: int, **kwargs) -> GuildMember:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
487
        data = await self._http.patch(
488
            f"guilds/{self.id}/members/{_id}", data=kwargs
489
        )
490
        return GuildMember.from_dict(construct_client_dict(self._client, data))
491
492
    async def ban(
493
            self,
494
            member_id: int,
495
            reason: str = None,
496
            delete_message_days: int = None
497
    ):
498
        """
499
        Parameters
500
        ----------
501
        member_id : :class:`int`
502
            ID of the guild member to ban.
503
        reason : Optional[:class:`str`]
504
            Reason for the kick.
505
        delete_message_days : Optional[:class:`int`]
506
            Number of days to delete messages for (0-7)
507
        """
508
        headers = {}
509
510
        if reason is not None:
511
            headers["X-Audit-Log-Reason"] = reason
512
513
        data = {}
514
515
        if delete_message_days is not None:
516
            data["delete_message_days"] = delete_message_days
517
518
        await self._http.put(
519
            f"/guilds/{self.id}/bans/{member_id}",
520
            data=data,
521
            headers=headers
522
        )
523
524
    async def kick(self, member_id: int, reason: Optional[str] = None):
525
        """|coro|
526
        Kicks a guild member.
527
        Parameters
528
        ----------
529
        member_id : :class:`int`
530
            ID of the guild member to kick.
531
        reason : Optional[:class:`str`]
532
            Reason for the kick.
533
        """
534
535
        headers = {}
536
537
        if reason is not None:
538
            headers["X-Audit-Log-Reason"] = reason
539
540
        await self._http.delete(
541
            f"/guilds/{self.id}/members/{member_id}",
542
            header=headers
543
        )
544
545
    async def get_roles(self) -> AsyncGenerator[Role, None]:
546
        """|coro|
547
        Fetches all the roles in the guild.
548
549
        Yields
550
        -------
551
        AsyncGenerator[:class:`~pincer.objects.guild.role.Role`, :data:`None`]
552
            An async generator of Role objects.
553
        """
554
        data = await self._http.get(f"guilds/{self.id}/roles")
555
        for role_data in data:
556
            yield Role.from_dict(construct_client_dict(self._client, role_data))
557
558
    @overload
559
    async def create_role(
560
            self,
561
            reason: Optional[str] = None,
562
            *,
563
            name: Optional[str] = "new role",
564
            permissions: Optional[str] = None,
565
            color: Optional[int] = 0,
566
            hoist: Optional[bool] = False,
567
            icon: Optional[str] = None,
568
            unicode_emoji: Optional[str] = None,
569
            mentionable: Optional[bool] = False,
570
    ) -> Role:
571
        """|coro|
572
        Creates a new role for the guild.
573
        Requires the ``MANAGE_ROLES`` permission.
574
575
        Parameters
576
        ----------
577
        reason : Optional[:class:`str`]
578
            Reason for creating the role. |default| :data:`None`
579
        name : Optional[:class:`str`]
580
            name of the role |default| :data:`"new role"`
581
        permissions : Optional[:class:`str`]
582
            bitwise value of the enabled/disabled
583
            permissions, set to @everyone permissions
584
            by default |default| :data:`None`
585
        color : Optional[:class:`int`]
586
            RGB color value |default| :data:`0`
587
        hoist : Optional[:class:`bool`]
588
            whether the role should be displayed
589
            separately in the sidebar |default| :data:`False`
590
        icon : Optional[:class:`str`]
591
            the role's icon image (if the guild has
592
            the ``ROLE_ICONS`` feature) |default| :data:`None`
593
        unicode_emoji : Optional[:class:`str`]
594
            the role's unicode emoji as a standard emoji (if the guild
595
            has the ``ROLE_ICONS`` feature) |default| :data:`None`
596
        mentionable : Optional[:class:`bool`]
597
            whether the role should be mentionable |default| :data:`False`
598
599
        Returns
600
        -------
601
        :class:`~pincer.objects.guild.role.Role`
602
            The new role object.
603
        """
604
        ...
605
606
    async def create_role(
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
607
            self,
608
            reason: Optional[str] = None,
609
            **kwargs
610
    ) -> Role:
611
        return Role.from_dict(
612
            construct_client_dict(
613
                self._client,
614
                await self._http.post(
615
                    f"guilds/{self.id}/roles",
616
                    data=kwargs,
617
                    headers=remove_none({"X-Audit-Log-Reason": reason})
618
                ),
619
            )
620
        )
621
622
    async def edit_role_position(
623
            self,
624
            id: Snowflake,
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in id.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
625
            reason: Optional[str] = None,
626
            position: Optional[int] = None
627
    ) -> AsyncGenerator[Role, None]:
628
        """|coro|
629
        Edits the position of a role.
630
631
        Parameters
632
        ----------
633
        id : :class:`~pincer.utils.snowflake.Snowflake`
634
            The role ID
635
        reason : Optional[:class:`str`]
636
            Reason for editing the role position. |default| :data:`None`
637
        position : Optional[:class:`int`]
638
            Sorting position of the role |default| :data:`None`
639
640
        Yields
641
        -------
642
        AsyncGenerator[:class:`~pincer.objects.guild.role.Role`, :data:`None`]
643
            An async generator of all of the guild's role objects.
644
        """
645
        data = await self._http.patch(
646
            f"guilds/{self.id}/roles",
647
            data={"id": id, "position": position},
648
            headers=remove_none({"X-Audit-Log-Reason": reason})
649
        )
650
        for role_data in data:
651
            yield Role.from_dict(construct_client_dict(self._client, role_data))
652
653
    @overload
654
    async def edit_role(
655
            self,
656
            id: Snowflake,
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in id.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
657
            reason: Optional[str] = None,
658
            *,
659
            name: Optional[str] = None,
660
            permissions: Optional[str] = None,
661
            color: Optional[int] = None,
662
            hoist: Optional[bool] = None,
663
            icon: Optional[str] = None,
664
            unicode_emoji: Optional[str] = None,
665
            mentionable: Optional[bool] = None,
666
    ) -> Role:
667
        """|coro|
668
        Edits a role.
669
        Requires the ``MANAGE_ROLES`` permission.
670
671
        Parameters
672
        ----------
673
        id : :class:`~pincer.utils.snowflake.Snowflake`
674
            The role ID
675
        reason : Optional[:class:`str`]
676
            Reason for editing the role |default| :data:`None`
677
        name : Optional[:class:`str`]
678
            Name of the role |default| :data:`None`
679
        permissions : Optional[:class:`str`]
680
            Bitwise value of the enabled/disabled
681
            permissions |default| :data:`None`
682
        color : Optional[:class:`int`]
683
            RGB color value |default| :data:`None`
684
        hoist : Optional[:class:`bool`]
685
            Whether the role should be displayed
686
            separately in the sidebar |default| :data:`None`
687
        icon : Optional[:class:`str`]
688
            The role's icon image (if the guild has
689
            the ``ROLE_ICONS`` feature) |default| :data:`None`
690
        unicode_emoji : Optional[:class:`str`]
691
            The role's unicode emoji as a standard emoji (if the guild
692
            has the ``ROLE_ICONS`` feature) |default| :data:`None`
693
        mentionable : Optional[:class:`bool`]
694
            Whether the role should be mentionable |default| :data:`None`
695
696
        Returns
697
        -------
698
        :class:`~pincer.objects.guild.role.Role`
699
            The edited role object.
700
        """
701
        ...
702
703
    async def edit_role(
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
704
            self,
705
            id: Snowflake,
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in id.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
706
            reason: Optional[str] = None,
707
            **kwargs
708
    ) -> Role:
709
        return Role.from_dict(
710
            construct_client_dict(
711
                self._client,
712
                await self._http.patch(
713
                    f"guilds/{self.id}/roles/{id}",
714
                    data=kwargs,
715
                    headers=remove_none({"X-Audit-Log-Reason": reason})
716
                ),
717
            )
718
        )
719
720
    async def delete_role(self, id: Snowflake, reason: Optional[str] = None):
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in id.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
721
        """|coro|
722
        Deletes a role.
723
        Requires the `MANAGE_ROLES` permission.
724
725
        Parameters
726
        ----------
727
        id : :class:`~pincer.utils.snowflake.Snowflake`
728
            The role ID
729
        reason : Optional[:class:`str`]
730
            The reason for deleting the role |default| :data:`None`
731
        """
732
        await self._http.delete(
733
            f"guilds/{self.id}/roles/{id}",
734
            headers=remove_none({"X-Audit-Log-Reason": reason})
735
        )
736
737
    async def get_bans(self) -> AsyncGenerator[Ban, None]:
738
        """|coro|
739
        Fetches all the bans in the guild.
740
741
        Yields
742
        -------
743
        AsyncGenerator[:class:`~pincer.objects.guild.ban.Ban`, :data:`None`]
744
            An async generator of Ban objects.
745
        """
746
        data = await self._http.get(f"guilds/{self.id}/bans")
747
        for ban_data in data:
748
            yield Ban.from_dict(construct_client_dict(self._client, ban_data))
749
750
    async def get_ban(self, id: Snowflake) -> Ban:
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in id.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
751
        """|coro|
752
        Fetches a ban from the guild.
753
754
        Parameters
755
        ----------
756
        id : :class:`~pincer.utils.snowflake.Snowflake`
757
            The user ID
758
759
        Returns
760
        -------
761
        :class:`~pincer.objects.guild.ban.Ban`
762
            The Ban object.
763
        """
764
        return Ban.from_dict(
765
            construct_client_dict(
766
                self._client,
767
                await self._http.get(f"guilds/{self.id}/bans/{id}"),
768
            )
769
        )
770
771
    async def unban(self, id: Snowflake, reason: Optional[str] = None):
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in id.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
772
        """|coro|
773
        Unbans a user from the guild.
774
775
        Parameters
776
        ----------
777
        id : :class:`~pincer.utils.snowflake.Snowflake`
778
            The user ID
779
        reason : Optional[:class:`str`]
780
            The reason for unbanning the user |default| :data:`None`
781
        """
782
        await self._http.delete(
783
            f"guilds/{self.id}/bans/{id}",
784
            headers=remove_none({"X-Audit-Log-Reason": reason})
785
        )
786
787
    @overload
788
    async def edit(
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (20/15).
Loading history...
789
            self,
790
            *,
791
            name: Optional[str] = None,
792
            region: Optional[str] = None,
793
            verification_level: Optional[int] = None,
794
            default_message_notifications: Optional[int] = None,
795
            explicit_content_filter: Optional[int] = None,
796
            afk_channel_id: Optional[Snowflake] = None,
797
            afk_timeout: Optional[int] = None,
798
            icon: Optional[str] = None,
799
            owner_id: Optional[Snowflake] = None,
800
            splash: Optional[str] = None,
801
            discovery_splash: Optional[str] = None,
802
            banner: Optional[str] = None,
803
            system_channel_id: Optional[Snowflake] = None,
804
            system_channel_flags: Optional[int] = None,
805
            rules_channel_id: Optional[Snowflake] = None,
806
            public_updates_channel_id: Optional[Snowflake] = None,
807
            preferred_locale: Optional[str] = None,
808
            features: Optional[List[GuildFeature]] = None,
809
            description: Optional[str] = None,
810
    ) -> Guild:
811
        """|coro|
812
        Modifies the guild
813
814
        Parameters
815
        ----------
816
        name : Optional[:class:`str`]
817
            Guild name |default| :data:`None`
818
        region : Optional[:class:`str`]
819
            Guild voice region ID |default| :data:`None`
820
        verification_level : Optional[:class:`int`]
821
            Verification level |default| :data:`None`
822
        default_message_notifications : Optional[:class:`int`]
823
            Default message notification level |default| :data:`None`
824
        explicit_content_filter : Optional[:class:`int`]
825
            Explicit content filter level |default| :data:`None`
826
        afk_channel_id : Optional[:class:`~pincer.utils.snowflake.Snowflake`]
827
            ID for AFK channel |default| :data:`None`
828
        afk_timeout : Optional[:class:`int`]
829
            AFK timeout in seconds |default| :data:`None`
830
        icon : Optional[:class:`str`]
831
            base64 1024x1024 png/jpeg/gif image for the guild icon
832
            (can be animated gif when the server
833
            has the `ANIMATED_ICON` feature) |default| :data:`None`
834
        owner_id : Optional[:class:`~pincer.utils.snowflake.Snowflake`]
835
            User ID to transfer guild ownership to (must be owner) |default| :data:`None`
836
        splash : Optional[:class:`str`]
837
            base64 16:9 png/jpeg image for the guild splash (when the
838
            server has the `INVITE_SPLASH` feature) |default| :data:`None`
839
        discovery_splash : Optional[:class:`str`]
840
            base64 16:9 png/jpeg image for the guild discovery splash
841
            (when the server has the `DISCOVERABLE` feature) |default| :data:`None`
842
        banner : Optional[:class:`str`]
843
            base64 16:9 png/jpeg image for the guild banner (when the
844
            server has the `BANNER` feature) |default| :data:`None`
845
        system_channel_id : Optional[:class:`~pincer.utils.snowflake.Snowflake`]
846
            The ID of the channel where guild notices such as welcome
847
            messages and boost events are posted |default| :data:`None`
848
        system_channel_flags : Optional[:class:`int`]
849
            System channel flags |default| :data:`None`
850
        rules_channel_id : Optional[:class:`~pincer.utils.snowflake.Snowflake`]
851
            The ID of the channel where Community guilds display rules
852
            and/or guidelines |default| :data:`None`
853
        public_updates_channel_id : Optional[:class:`~pincer.utils.snowflake.Snowflake`]
854
            The ID of the channel where admins and moderators of
855
            Community guilds receive notices from Discord |default| :data:`None`
856
        preferred_locale : Optional[:class:`str`]
857
            The preferred locale of a Community guild used in server
858
            discovery and notices from Discord; defaults to "en-US" |default| :data:`None`
859
        features : Optional[List[:class:`GuildFeature`]]
860
            Enabled guild features |default| :data:`None`
861
        description : Optional[:class:`str`]
862
            The description for the guild, if the guild is discoverable |default| :data:`None`
863
864
        Returns
865
        -------
866
        :class:`~pincer.objects.guild.Guild`
867
            The modified guild object.
868
        """
869
        ...
870
871
    async def edit(self, **kwargs) -> Guild:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
872
        g = await self._http.patch(f"guilds/{self.id}", data=kwargs)
873
        return Guild.from_dict(construct_client_dict(self._client, g))
874
875
    async def preview(self) -> GuildPreview:
876
        """|coro|
877
        Previews the guild.
878
879
        Returns
880
        -------
881
        :class:`~pincer.objects.guild.guild.GuildPreview`
882
            The guild preview object.
883
        """
884
        data = await self._http.get(f"guilds/{self.id}/preview")
885
        return GuildPreview.from_dict(data)
886
887
    async def delete(self):
888
        """|coro|
889
        Deletes the guild. Returns `204 No Content` on success.
890
        """
891
        await self._http.delete(f"guilds/{self.id}")
892
893
    async def prune_count(
894
            self,
895
            days: Optional[int] = 7,
896
            include_roles: Optional[str] = None
897
    ) -> int:
898
        """|coro|
899
        Returns the number of members that
900
        would be removed in a prune operation.
901
        Requires the ``KICK_MEMBERS`` permission.
902
903
        Parameters
904
        ----------
905
        days : Optional[:class:`int`]
906
            Number of days to count prune for (1-30) |default| :data:`7`
907
        include_roles : Optional[:class:`str`]
908
            Comma-delimited array of Snowflakes;
909
            role(s) to include |default| :data:`None`
910
911
        Returns
912
        -------
913
        :class:`int`
914
            The number of members that would be removed.
915
        """
916
        return await self._http.get(
917
            f"guilds/{self.id}/prune?{days=}&{include_roles=!s}"
918
        )["pruned"]
919
920
    async def prune(
921
            self,
922
            days: Optional[int] = 7,
923
            compute_prune_days: Optional[bool] = True,
924
            include_roles: Optional[List[Snowflake]] = None,
925
            reason: Optional[str] = None
926
    ) -> int:
927
        """|coro|
928
        Prunes members from the guild. Requires the ``KICK_MEMBERS`` permission.
929
930
        Parameters
931
932
        Parameters
933
        ----------
934
        days : Optional[:class:`int`]
935
            Number of days to prune (1-30) |default| :data:`7`
936
        compute_prune_days : Optional[:class:`bool`]
937
            Whether ``pruned`` is returned, discouraged for large guilds
938
            |default| :data:`True`
939
        include_roles : Optional[List[:class:`~pincer.utils.snowflake.Snowflake`]]
940
            role(s) to include |default| :data:`None`
941
        reason : Optional[:class:`str`]
942
            Reason for the prune |default| :data:`None`
943
944
        Returns
945
        -------
946
        :class:`int`
947
            The number of members that were removed.
948
        """
949
        return await self._http.post(
950
            f"guilds/{self.id}/prune",
951
            data={
952
                "days": days,
953
                "compute_prune_days": compute_prune_days,
954
                "include_roles": include_roles
955
            },
956
            headers=remove_none({"X-Audit-Log-Reason": reason})
957
        )["pruned"]
958
959
    async def get_voice_regions(self) -> AsyncGenerator[VoiceRegion, None]:
960
        """|coro|
961
        Returns an async generator of voice regions.
962
963
        Yields
964
        -------
965
        AsyncGenerator[:class:`~pincer.objects.voice.VoiceRegion`, :data:`None`]
966
            An async generator of voice regions.
967
        """
968
        data = await self._http.get(f"guilds/{self.id}/regions")
969
        for voice_region_data in data:
970
            yield VoiceRegion.from_dict(
971
                construct_client_dict(self._client, voice_region_data))
972
973
    async def get_invites(self) -> AsyncGenerator[Invite, None]:
974
        """|coro|
975
        Returns an async generator of invites for the guild.
976
        Requires the ``MANAGE_GUILD`` permission.
977
978
        Yields
979
        -------
980
        AsyncGenerator[:class:`~pincer.objects.invite.Invite`, :data:`None`]
981
            An async generator of invites.
982
        """
983
        data = await self._http.get(f"guilds/{self.id}/invites")
984
        for invite_data in data:
985
            yield Invite.from_dict(
986
                construct_client_dict(self._client, invite_data))
987
988
    async def get_integrations(self) -> AsyncGenerator[Integration, None]:
989
        """|coro|
990
        Returns an async generator of integrations for the guild.
991
        Requires the ``MANAGE_GUILD`` permission.
992
993
        Yields
994
        -------
995
        AsyncGenerator[:class:`~pincer.objects.integration.Integration`, :data:`None`]
996
            An async generator of integrations.
997
        """
998
        data = await self._http.get(f"guilds/{self.id}/integrations")
999
        for integration_data in data:
1000
            yield Integration.from_dict(
1001
                construct_client_dict(self._client, integration_data))
1002
1003
    async def delete_integration(
1004
            self,
1005
            integration: Integration,
1006
            reason: Optional[str] = None
1007
    ):
1008
        """|coro|
1009
        Deletes an integration.
1010
        Requires the ``MANAGE_GUILD`` permission.
1011
1012
        Parameters
1013
        ----------
1014
        integration : :class:`~pincer.objects.integration.Integration`
1015
            The integration to delete.
1016
        reason : Optional[:class:`str`]
1017
            Reason for the deletion |default| :data:`None`
1018
        """
1019
        await self._http.delete(
1020
            f"guilds/{self.id}/integrations/{integration.id}",
1021
            headers=remove_none({"X-Audit-Log-Reason": reason})
1022
        )
1023
1024
    async def get_widget_settings(self) -> GuildWidget:
1025
        """|coro|
1026
        Returns the guild widget settings.
1027
        Requires the ``MANAGE_GUILD`` permission.
1028
1029
        Returns
1030
        -------
1031
        :class:`~pincer.objects.guild.widget.GuildWidget`
1032
            The guild widget settings.
1033
        """
1034
        return GuildWidget.from_dict(
1035
            construct_client_dict(
1036
                self._client,
1037
                await self._http.get(f"guilds/{self.id}/widget")
1038
            )
1039
        )
1040
1041
    async def modify_widget(
1042
            self,
1043
            reason: Optional[str] = None,
1044
            **kwargs
1045
    ) -> GuildWidget:
1046
        """|coro|
1047
        Modifies the guild widget for the guild.
1048
        Requires the ``MANAGE_GUILD`` permission.
1049
1050
        Parameters
1051
        ----------
1052
        reason : Optional[:class:`str`]
1053
            Reason for the modification |default| :data:`None`
1054
        \\*\\*kwargs
1055
            The widget settings to modify
1056
1057
        Returns
1058
        -------
1059
        :class:`~pincer.objects.guild.widget.GuildWidget`
1060
            The updated GuildWidget object
1061
        """
1062
        data = await self._http.patch(
1063
            f"guilds/{self.id}/widget",
1064
            data=kwargs,
1065
            headers=remove_none({"X-Audit-Log-Reason": reason})
1066
        )
1067
        return GuildWidget.from_dict(construct_client_dict(self._client, data))
1068
1069
    async def get_widget(self) -> Dict[str, JSONSerializable]:
1070
        """|coro|
1071
        Returns the widget for the guild
1072
        """
1073
        return await self._http.get(f"guilds/{self.id}/widget.json")
1074
1075
    @property
1076
    async def vanity_url(self) -> Invite:
1077
        """|coro|
1078
        Returns the Vanity URL for the guild.
1079
        Requires the ``MANAGE_GUILD`` permission.
1080
        ``code`` will be null if a vanity URL has not been set.
1081
1082
        Returns
1083
        -------
1084
        :class:`~pincer.objects.guild.invite.Invite`
1085
            The vanity url for the guild.
1086
        """
1087
        data = await self._http.get(f"guilds/{self.id}/vanity-url")
1088
        return Invite.from_dict(construct_client_dict(self._client, data))
1089
1090
    async def get_widget_image(self, style: Optional[
1091
        str] = "shield") -> str:  # TODO Replace str with ImageURL object
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
1092
        """|coro|
1093
        Returns a PNG image widget for the guild.
1094
        Requires no permissions or authentication.
1095
1096
        Widget Style Options
1097
        -------------------
1098
        * [``shield``](https://discord.com/api/guilds/81384788765712384/widget.png?style=shield)
1099
          shield style widget with Discord icon and guild members online count
1100
        * [``banner1``](https://discord.com/api/guilds/81384788765712384/widget.png?style=banner1)
1101
          large image with guild icon, name and online count.
1102
          "POWERED BY DISCORD" as the footer of the widget
1103
        * [``banner2``](https://discord.com/api/guilds/81384788765712384/widget.png?style=banner2)
1104
          smaller widget style with guild icon, name and online count.
1105
          Split on the right with Discord logo
1106
        * [``banner3``](https://discord.com/api/guilds/81384788765712384/widget.png?style=banner3)
1107
          large image with guild icon, name and online count.
1108
          In the footer, Discord logo on the
1109
          left and "Chat Now" on the right
1110
        * [``banner4``](https://discord.com/api/guilds/81384788765712384/widget.png?style=banner4)
1111
          large Discord logo at the top of the widget.
1112
          Guild icon, name and online count in the middle portion
1113
          of the widget and a "JOIN MY SERVER" button at the bottom
1114
1115
        Parameters
1116
        ----------
1117
        style : Optional[:class:`str`]
1118
            Style of the widget image returned |default| :data:`"shield"`
1119
1120
        Returns
1121
        -------
1122
        :class:`str`
1123
            A PNG image of the guild widget.
1124
        """
1125
        return await self._http.get(f"guilds/{self.id}/widget.png?{style=!s}")
1126
1127
    async def get_welcome_screen(self) -> WelcomeScreen:
1128
        """Returns the welcome screen for the guild.
1129
1130
        Returns
1131
        -------
1132
        :class:`~pincer.objects.guild.welcome_screen.WelcomeScreen`
1133
            The welcome screen for the guild.
1134
        """
1135
        data = await self._http.get(f"guilds/{self.id}/welcome-screen")
1136
        return WelcomeScreen.from_dict(
1137
            construct_client_dict(self._client, data))
1138
1139
    async def modify_welcome_screen(
1140
            self,
1141
            enabled: Optional[bool] = None,
1142
            welcome_channels: Optional[List[WelcomeScreenChannel]] = None,
1143
            description: Optional[str] = None,
1144
            reason: Optional[str] = None
1145
    ) -> WelcomeScreen:
1146
        """|coro|
1147
        Modifies the guild's Welcome Screen.
1148
        Requires the ``MANAGE_GUILD`` permission.
1149
1150
        Parameters
1151
        ----------
1152
        enabled : Optional[:class:`bool`]
1153
            Whether the welcome screen is enabled |default| :data:`None`
1154
        welcome_channels : Optional[List[:class:`~pincer.objects.guild.welcome_screen.WelcomeScreenChannel`]]
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (109/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
1155
            Channels linked in the welcome screen and
1156
            their display options |default| :data:`None`
1157
        description : Optional[:class:`str`]
1158
            The server description to show
1159
            in the welcome screen |default| :data:`None`
1160
        reason : Optional[:class:`str`]
1161
            Reason for the modification |default| :data:`None`
1162
1163
        Returns
1164
        -------
1165
        :class:`~pincer.objects.guild.welcome_screen.WelcomeScreen`
1166
            The updated WelcomeScreen object
1167
        """
1168
        data = await self._http.patch(
1169
            f"guilds/{self.id}/welcome-screen",
1170
            data={
1171
                "enabled": enabled,
1172
                "welcome_channels": welcome_channels,
1173
                "description": description
1174
            },
1175
            headers=remove_none({"X-Audit-Log-Reason": reason})
1176
        )
1177
        return WelcomeScreen.from_dict(
1178
            construct_client_dict(self._client, data))
1179
1180
    async def modify_current_user_voice_state(
1181
            self,
1182
            channel_id: Snowflake,
1183
            suppress: Optional[bool] = None,
1184
            request_to_speak_timestamp: Optional[Timestamp] = None
1185
    ):
1186
        """|coro|
1187
        Updates the current user's voice state.
1188
1189
        There are currently several caveats for this endpoint:
1190
        * ``channel_id`` must currently point to a stage channel
1191
        * current user must already have joined ``channel_id``
1192
        * You must have the ``MUTE_MEMBERS`` permission to
1193
          unsuppress yourself. You can always suppress yourself.
1194
        * You must have the ``REQUEST_TO_SPEAK`` permission to request
1195
          to speak. You can always clear your own request to speak.
1196
        * You are able to set ``request_to_speak_timestamp`` to any
1197
          present or future time.
1198
1199
        Parameters
1200
        ----------
1201
        channel_id : :class:`~pincer.utils.snowflake.Snowflake`
1202
            The ID of the channel the user is currently in
1203
        suppress : Optional[:class:`bool`]
1204
            Toggles the user's suppress state |default| :data:`None`
1205
        request_to_speak_timestamp : Optional[:class:`~pincer.utils.timestamp.Timestamp`]
1206
            Sets the user's request to speak
1207
        """
1208
        await self._http.patch(
1209
            f"guilds/{self.id}/voice-states/@me",
1210
            data={
1211
                "channel_id": channel_id,
1212
                "suppress": suppress,
1213
                "request_to_speak_timestamp": request_to_speak_timestamp
1214
            }
1215
        )
1216
1217
    async def modify_user_voice_state(
1218
            self,
1219
            user: User,
1220
            channel_id: Snowflake,
1221
            suppress: Optional[bool] = None
1222
    ):
1223
        """|coro|
1224
        Updates another user's voice state.
1225
1226
        There are currently several caveats for this endpoint:
1227
        * ``channel_id`` must currently point to a stage channel
1228
        * User must already have joined ``channel_id``
1229
        * You must have the ``MUTE_MEMBERS`` permission.
1230
          (Since suppression is the only thing that is available currently.)
1231
        * When unsuppressed, non-bot users will have their
1232
          ``request_to_speak_timestamp`` set to the current time.
1233
          Bot users will not.
1234
        * When suppressed, the user will have their
1235
          ``request_to_speak_timestamp`` removed.
1236
1237
        Parameters
1238
        ----------
1239
        user : :class:`~pincer.objects.guild.member.Member`
1240
            The user to update
1241
        channel_id : :class:`~pincer.utils.snowflake.Snowflake`
1242
            The ID of the channel the user is currently in
1243
        suppress : Optional[:class:`bool`]
1244
            Toggles the user's suppress state |default| :data:`None`
1245
        """
1246
        await self._http.patch(
1247
            f"guilds/{self.id}/voice-states/{user.id}",
1248
            data={
1249
                "channel_id": channel_id,
1250
                "suppress": suppress
1251
            }
1252
        )
1253
1254
    async def get_audit_log(self) -> AuditLog:
1255
        """|coro|
1256
        Returns an audit log object for the guild.
1257
        Requires the ``VIEW_AUDIT_LOG`` permission.
1258
1259
        Returns
1260
        -------
1261
        :class:`~pincer.objects.guild.audit_log.AuditLog`
1262
            The audit log object for the guild.
1263
        """
1264
        return AuditLog.from_dict(
1265
            construct_client_dict(
1266
                self._client,
1267
                await self._http.get(f"guilds/{self.id}/audit-logs")
1268
            )
1269
        )
1270
1271
    async def get_emojis(self) -> AsyncGenerator[Emoji, None]:
1272
        """|coro|
1273
        Returns an async generator of the emojis in the guild.
1274
1275
        Yields
1276
        ------
1277
        :class:`~pincer.objects.guild.emoji.Emoji`
1278
            The emoji object.
1279
        """
1280
        data = await self._http.get(f"guilds/{self.id}/emojis")
1281
        for emoji_data in data:
1282
            yield Emoji.from_dict(
1283
                construct_client_dict(self._client, emoji_data)
1284
            )
1285
1286
    async def get_emoji(self, id: Snowflake) -> Emoji:
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in id.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
1287
        """|coro|
1288
        Returns an emoji object for the given ID.
1289
1290
        Parameters
1291
        ----------
1292
        id : :class:`~pincer.utils.snowflake.Snowflake`
1293
            The ID of the emoji
1294
1295
        Returns
1296
        -------
1297
        :class:`~pincer.objects.guild.emoji.Emoji`
1298
            The emoji object.
1299
        """
1300
        return Emoji.from_dict(
1301
            construct_client_dict(
1302
                self._client,
1303
                await self._http.get(f"guilds/{self.id}/emojis/{id}")
1304
            )
1305
        )
1306
1307
    async def create_emoji(
0 ignored issues
show
Bug Best Practice introduced by
The default value [] might cause unintended side-effects.

Objects as default values are only created once in Python and not on each invocation of the function. If the default object is modified, this modification is carried over to the next invocation of the method.

# Bad:
# If array_param is modified inside the function, the next invocation will
# receive the modified object.
def some_function(array_param=[]):
    # ...

# Better: Create an array on each invocation
def some_function(array_param=None):
    array_param = array_param or []
    # ...
Loading history...
1308
        self,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
1309
        *,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
1310
        name: str,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
1311
        image: File,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
1312
        roles: List[Snowflake] = [],
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
1313
        reason: Optional[str] = None
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
1314
    ) -> Emoji:
1315
        """|coro|
1316
        Creates a new emoji for the guild.
1317
        Requires the ``MANAGE_EMOJIS_AND_STICKERS`` permission.
1318
1319
        Emojis and animated emojis have a maximum file size of 256kb.
1320
        Attempting to upload an emoji larger than this limit will fail.
1321
1322
        Parameters
1323
        ----------
1324
        name : :class:`str`
1325
            Name of the emoji
1326
        image : :class:`~pincer.objects.message.file.File`
1327
            The File for the 128x128 emoji image data
1328
        roles : List[:class:`~pincer.utils.snowflake.Snowflake`]
1329
            Roles allowed to use this emoji |default| :data:`[]`
1330
        reason : Optional[:class:`str`]
1331
            The reason for creating the emoji |default| :data:`None`
1332
1333
        Returns
1334
        -------
1335
        :class:`~pincer.objects.guild.emoji.Emoji`
1336
            The newly created emoji object.
1337
        """
1338
        data = await self._http.post(
1339
            f"guilds/{self.id}/emojis",
1340
            data={
1341
                "name": name,
1342
                "image": image.uri,
1343
                "roles": roles
1344
            },
1345
            headers=remove_none({"X-Audit-Log-Reason": reason})
1346
        )
1347
        return Emoji.from_dict(
1348
            construct_client_dict(self._client, data)
1349
        )
1350
1351
    async def edit_emoji(
1352
            self,
1353
            id: Snowflake,
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in id.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
1354
            *,
1355
            name: Optional[str] = None,
1356
            roles: Optional[List[Snowflake]] = None,
1357
            reason: Optional[str] = None
1358
    ) -> Emoji:
1359
        """|coro|
1360
        Modifies the given emoji.
1361
        Requires the ``MANAGE_EMOJIS_AND_STICKERS`` permission.
1362
1363
        Parameters
1364
        ----------
1365
        id : :class:`~pincer.utils.snowflake.Snowflake`
1366
            The ID of the emoji
1367
        name : Optional[:class:`str`]
1368
            Name of the emoji |default| :data:`None`
1369
        roles : Optional[List[:class:`~pincer.utils.snowflake.Snowflake`]]
1370
            Roles allowed to use this emoji |default| :data:`None`
1371
        reason : Optional[:class:`str`]
1372
            The reason for editing the emoji |default| :data:`None`
1373
1374
        Returns
1375
        -------
1376
        :class:`~pincer.objects.guild.emoji.Emoji`
1377
            The modified emoji object.
1378
        """
1379
        data = await self._http.patch(
1380
            f"guilds/{self.id}/emojis/{id}",
1381
            data={
1382
                "name": name,
1383
                "roles": roles
1384
            },
1385
            headers=remove_none({"X-Audit-Log-Reason": reason})
1386
        )
1387
        return Emoji.from_dict(
1388
            construct_client_dict(self._client, data)
1389
        )
1390
1391
    async def delete_emoji(
1392
            self,
1393
            id: Snowflake,
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in id.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
1394
            *,
1395
            reason: Optional[str] = None
1396
    ):
1397
        """|coro|
1398
        Deletes the given emoji.
1399
        Requires the ``MANAGE_EMOJIS_AND_STICKERS`` permission.
1400
1401
        Parameters
1402
        ----------
1403
        id : :class:`~pincer.utils.snowflake.Snowflake`
1404
            The ID of the emoji
1405
        reason : Optional[:class:`str`]
1406
            The reason for deleting the emoji |default| :data:`None`
1407
        """
1408
        await self._http.delete(
1409
            f"guilds/{self.id}/emojis/{id}",
1410
            headers=remove_none({"X-Audit-Log-Reason": reason})
1411
        )
1412
1413
    async def get_templates(self) -> AsyncGenerator[GuildTemplate, None]:
1414
        """|coro|
1415
        Returns an async generator of the guild templates.
1416
1417
        Yields
1418
        -------
1419
        AsyncGenerator[:class:`~pincer.objects.guild.template.GuildTemplate`, :data:`None`]
1420
            The guild template object.
1421
        """
1422
        data = await self._http.get(f"guilds/{self.id}/templates")
1423
        for template_data in data:
1424
            yield GuildTemplate.from_dict(
1425
                construct_client_dict(self._client, template_data)
1426
            )
1427
1428
    async def create_template(
1429
            self,
1430
            name: str,
1431
            description: Optional[str] = None
1432
    ) -> GuildTemplate:
1433
        """|coro|
1434
        Creates a new template for the guild.
1435
        Requires the ``MANAGE_GUILD`` permission.
1436
1437
        Parameters
1438
        ----------
1439
        name : :class:`str`
1440
            Name of the template (1-100 characters)
1441
        description : Optional[:class:`str`]
1442
            Description of the template
1443
            (0-120 characters) |default| :data:`None`
1444
        Returns
1445
        -------
1446
        :class:`~pincer.objects.guild.template.GuildTemplate`
1447
            The newly created template object.
1448
        """
1449
        data = await self._http.post(
1450
            f"guilds/{self.id}/templates",
1451
            data={
1452
                "name": name,
1453
                "description": description
1454
            }
1455
        )
1456
        return GuildTemplate.from_dict(
1457
            construct_client_dict(self._client, data)
1458
        )
1459
1460
    async def sync_template(
1461
            self,
1462
            template: GuildTemplate
1463
    ) -> GuildTemplate:
1464
        """|coro|
1465
        Syncs the given template.
1466
        Requires the ``MANAGE_GUILD`` permission.
1467
1468
        Parameters
1469
        ----------
1470
        template : :class:`~pincer.objects.guild.template.GuildTemplate`
1471
            The template to sync
1472
1473
        Returns
1474
        -------
1475
        :class:`~pincer.objects.guild.template.GuildTemplate`
1476
            The synced template object.
1477
        """
1478
        data = await self._http.put(
1479
            f"guilds/{self.id}/templates/{template.code}"
1480
        )
1481
        return GuildTemplate.from_dict(
1482
            construct_client_dict(self._client, data)
1483
        )
1484
1485
    async def edit_template(
1486
            self,
1487
            template: GuildTemplate,
1488
            *,
1489
            name: Optional[str] = None,
1490
            description: Optional[str] = None
1491
    ) -> GuildTemplate:
1492
        """|coro|
1493
        Modifies the template's metadata.
1494
        Requires the ``MANAGE_GUILD`` permission.
1495
1496
        Parameters
1497
        ----------
1498
        template : :class:`~pincer.objects.guild.template.GuildTemplate`
1499
            The template to edit
1500
        name : Optional[:class:`str`]
1501
            Name of the template (1-100 characters)
1502
            |default| :data:`None`
1503
        description : Optional[:class:`str`]
1504
            Description of the template (0-120 characters)
1505
            |default| :data:`None`
1506
1507
        Returns
1508
        -------
1509
        :class:`~pincer.objects.guild.template.GuildTemplate`
1510
            The edited template object.
1511
        """
1512
        data = await self._http.patch(
1513
            f"guilds/{self.id}/templates/{template.code}",
1514
            data={
1515
                "name": name,
1516
                "description": description
1517
            }
1518
        )
1519
        return GuildTemplate.from_dict(
1520
            construct_client_dict(self._client, data)
1521
        )
1522
1523
    async def delete_template(
1524
            self,
1525
            template: GuildTemplate
1526
    ) -> GuildTemplate:
1527
        """|coro|
1528
        Deletes the given template.
1529
        Requires the ``MANAGE_GUILD`` permission.
1530
1531
        Parameters
1532
        ----------
1533
        template : :class:`~pincer.objects.guild.template.GuildTemplate`
1534
            The template to delete
1535
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1536
        Returns
1537
        -------
1538
        :class:`~pincer.objects.guild.template.GuildTemplate`
1539
            The deleted template object.
1540
        """
1541
        data = await self._http.delete(
1542
            f"guilds/{self.id}/templates/{template.code}"
1543
        )
1544
        return GuildTemplate.from_dict(
1545
            construct_client_dict(self._client, data)
1546
        )
1547
1548
    @classmethod
1549
    async def sticker_packs(cls) -> Generator[StickerPack, None, None]:
1550
        """|coro|
1551
        Returns the list of sticker packs available to Nitro subscribers.
1552
1553
        Yields
1554
        ------
1555
        :class:`~pincer.objects.message.sticker.StickerPack`
1556
            a sticker pack
1557
        """
1558
        packs = await cls._http.get("sticker-packs")
0 ignored issues
show
Bug introduced by
The Class Guild does not seem to have a member named _http.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
1559
        return (StickerPack.from_dict(pack) for pack in packs)
1560
1561
    async def list_stickers(self) -> Generator[Sticker, None, None]:
1562
        """|coro|
1563
        Returns an array of sticker objects for the current guild.
1564
        Includes ``user`` fields if the bot has the ``MANAGE_EMOJIS_AND_STICKERS`` permission.
1565
1566
        Yields
1567
        ------
1568
        :class:`~pincer.objects.message.sticker.Sticker`
1569
            a sticker for the current guild
1570
        """
1571
        return (
1572
            Sticker.from_dict(sticker)
1573
            for sticker in await self._http.get(f"guild/{self.id}/stickers")
1574
        )
1575
1576
    async def get_sticker(self, _id: Snowflake):
1577
        """|coro|
1578
        Returns a sticker object for the current guild and sticker IDs.
1579
        Includes the ``user`` field if the bot has the ``MANAGE_EMOJIS_AND_STICKERS`` permission.
1580
1581
        Parameters
1582
        ----------
1583
        _id : int
1584
            id of the sticker
1585
1586
        Returns
1587
        -------
1588
        :class:`~pincer.objects.message.sticker.Sticker`
1589
            the sticker requested
1590
        """
1591
        sticker = await self._http.get(f"guilds/{self.id}/stickers/{_id}")
1592
        return Sticker.from_dict(sticker)
1593
1594
    async def create_sticker(
0 ignored issues
show
best-practice introduced by
Too many arguments (6/5)
Loading history...
1595
            self,
1596
            name: str,
1597
            tags: str,
1598
            file,
1599
            description: str = "",
1600
            reason: Optional[str] = None
1601
    ) -> Sticker:
1602
        """NOT IMPLEMENTED: DOES NOT WORK"""
1603
        raise NotImplementedError
1604
        # TODO: Fix this once File is fixed
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
1605
        # """|coro|
1606
        # Create a new sticker for the guild.
1607
        # Requires the ``MANAGE_EMOJIS_AND_STICKERS permission``.
1608
        #
1609
        # Parameters
1610
        # ----------
1611
        # name : str
1612
        #     name of the sticker (2-30 characters)
1613
        # tags : str
1614
        #     autocomplete/suggestion tags for the sticker (max 200 characters)
1615
        # file :
1616
        #     the sticker file to upload, must be a PNG, APNG, or Lottie JSON file, max 500 KB
1617
        # description : Optional[:class:`str`]
1618
        #     description of the sticker (empty or 2-100 characters) |default| :data:`""`
1619
        # reason : Optional[:class:`str`] |default| :data:`None`
1620
        #     reason for creating the sticker
1621
        #
1622
        # Returns
1623
        # -------
1624
        # :class:`~pincer.objects.message.sticker.Sticker`
1625
        #     the newly created sticker
1626
        # """
1627
        # sticker = await self._http.post(
1628
        #     f"guilds/{self.id}/stickers",
1629
        #     headers=remove_none({"X-Audit-Log-Reason": reason})
1630
        # )
1631
        #
1632
        # return Sticker.from_dict(sticker)
1633
1634
1635
    async def delete_sticker(self, _id: Snowflake) -> None:
1636
        """|coro|
1637
        Delete the given sticker.
1638
        Requires the ``MANAGE_EMOJIS_AND_STICKERS`` permission.
1639
1640
        Parameters
1641
        ----------
1642
        _id: Snowflake
1643
            id of the sticker
1644
        """
1645
        await self._http.delete(f"guilds/{self.id}/stickers/{_id}")
1646
1647
    async def get_webhooks(self) -> AsyncGenerator[Webhook, None]:
1648
        """|coro|
1649
        Returns an async generator of the guild webhooks.
1650
1651
        Yields
1652
        -------
1653
        AsyncGenerator[:class:`~pincer.objects.guild.webhook.Webhook`, None]
1654
            The guild webhook object.
1655
        """
1656
        data = await self._http.get(f"guilds/{self.id}/webhooks")
1657
        for webhook_data in data:
1658
            yield Webhook.from_dict(
1659
                construct_client_dict(self._client, webhook_data)
1660
            )
1661
1662
1663
    @classmethod
1664
    def from_dict(cls, data) -> Guild:
1665
        """
1666
        Parameters
1667
        ----------
1668
        data : :class:`Dict`
1669
            Guild data received from the discord API.
1670
        Returns
1671
        -------
1672
        :class:`~pincer.objects.guild.guild.Guild`
1673
            The new guild object.
1674
        Raises
1675
        ------
1676
        :class:`~pincer.exceptions.UnavailableGuildError`
1677
            The guild is unavailable due to a discord outage.
1678
        """
1679
        if data.get("unavailable", False):
1680
            raise UnavailableGuildError(
1681
                f"Guild \"{data['id']}\" is unavailable due to a discord"
1682
                " outage."
1683
            )
1684
1685
        return super().from_dict(data)
1686
1687
1688
@dataclass(repr=False)
1689
class UnavailableGuild(APIObject):
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
1690
    id: Snowflake
1691
    unavailable: bool = True
1692