Passed
Pull Request — main (#225)
by Yohann
01:48
created

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

Complexity

Conditions 1

Size

Total Lines 10
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 10
rs 10
c 0
b 0
f 0
cc 1
nop 1
1
# Copyright Pincer 2021-Present
0 ignored issues
show
introduced by
Missing module docstring
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 overload, TYPE_CHECKING
9
10
from .channel import Channel
0 ignored issues
show
introduced by
Cannot import 'channel' due to syntax error 'invalid syntax (<unknown>, line 251)'
Loading history...
11
from .member import GuildMember
12
from ...exceptions import UnavailableGuildError
13
from ...utils.api_object import APIObject
0 ignored issues
show
introduced by
Cannot import 'utils.api_object' due to syntax error 'invalid syntax (<unknown>, line 80)'
Loading history...
Bug introduced by
The name api_object does not seem to exist in module pincer.utils.
Loading history...
14
from ...utils.conversion import construct_client_dict
15
from ...utils.types import MISSING
16
17
if TYPE_CHECKING:
18
    from typing import Any, Dict, List, Optional, Union
19
20
    from .features import GuildFeature
21
    from .role import Role
22
    from .stage import StageInstance
23
    from .welcome_screen import WelcomeScreen
24
    from ..events.presence import PresenceUpdateEvent
25
    from ..message.emoji import Emoji
26
    from ..message.sticker import Sticker
27
    from ..user.voice_state import VoiceState
28
    from ...client import Client
0 ignored issues
show
introduced by
Cannot import 'client' due to syntax error 'invalid syntax (<unknown>, line 354)'
Loading history...
29
    from ...utils.timestamp import Timestamp
0 ignored issues
show
Bug introduced by
The name timestamp does not seem to exist in module pincer.utils.
Loading history...
introduced by
Cannot import 'utils.timestamp' due to syntax error 'invalid syntax (<unknown>, line 103)'
Loading history...
30
    from ...utils.types import APINullable
31
    from ...utils.snowflake import Snowflake
32
33
34
class PremiumTier(IntEnum):
35
    """Represents the boost tier of a guild.
36
    Attributes
37
    ----------
38
    NONE:
39
        Guild has not unlocked any Server Boost perks.
40
    TIER_1:
41
        Guild has unlocked Server Boost level 1 perks.
42
    TIER_2:
43
        Guild has unlocked Server Boost level 2 perks.
44
    TIER_3:
45
        Guild has unlocked Server Boost level 3 perks.
46
    """
47
    NONE = 0
48
    TIER_1 = 1
49
    TIER_2 = 2
50
    TIER_3 = 3
51
52
53
class GuildNSFWLevel(IntEnum):
54
    """Represents the NSFW level of a guild.
55
    Attributes
56
    ----------
57
    DEFAULT:
58
        Default NSFW level.
59
    EXPLICIT:
60
        Explicit NSFW level.
61
    SAFE:
62
        SAFE NSFW level.
63
    AGE_RESTRICTED:
64
        Age restricted NSFW level.
65
    """
66
    DEFAULT = 0
67
    EXPLICIT = 1
68
    SAFE = 2
69
    AGE_RESTRICTED = 3
70
71
72
class ExplicitContentFilterLevel(IntEnum):
73
    """Represents the filter content level of a guild.
74
    Attributes
75
    ----------
76
    DISABLED:
77
        Media content will not be scanned.
78
    MEMBERS_WITHOUT_ROLES:
79
        Media content sent by members without roles will be scanned.
80
    ALL_MEMBERS:
81
        Media content sent by all members will be scanned.
82
    """
83
    DISABLED = 0
84
    MEMBERS_WITHOUT_ROLES = 1
85
    ALL_MEMBERS = 2
86
87
88
class MFALevel(IntEnum):
89
    """Represents the multi factor authentication level of a guild.
90
    Attributes
91
    ----------
92
    NONE:
93
        Guild has no MFA/2FA requirement for moderation actions.
94
    ELEVATED:
95
        Guild has a 2FA requirement for moderation actions
96
    """
97
    NONE = 0
98
    ELEVATED = 1
99
100
101
class VerificationLevel(IntEnum):
102
    """Represents the verification level of a guild.
103
    Attributes
104
    ----------
105
    NONE:
106
        Unrestricted.
107
    LOW:
108
        Must have verified email on account.
109
    MEDIUM:
110
        Must be registered on Discord for longer than 5 minutes.
111
    HIGH:
112
        Must be a member of the server for longer than 10 minutes.
113
    VERY_HIGH:
114
        Must have a verified phone number.
115
    """
116
    NONE = 0
117
    LOW = 1
118
    MEDIUM = 2
119
    HIGH = 3
120
    VERY_HIGH = 4
121
122
123
class DefaultMessageNotificationLevel(IntEnum):
124
    """Represents the default message notification level of a guild.
125
    Attributes
126
    ----------
127
    ALL_MESSAGES:
128
        Members will receive notifications for all messages by default.
129
    ONLY_MENTIONS:
130
        Members will receive notifications only for messages that @mention them by default.
131
    """
132
    # noqa: E501
133
    ALL_MESSAGES = 0
134
    ONLY_MENTIONS = 1
135
136
137
class SystemChannelFlags(IntEnum):
138
    """Represents the system channel flags of a guild.
139
    Attributes
140
    ----------
141
    SUPPRESS_JOIN_NOTIFICATIONS:
142
        Suppress member join notifications.
143
    SUPPRESS_PREMIUM_SUBSCRIPTIONS:
144
        Suppress server boost notifications.
145
    SUPPRESS_GUILD_REMINDER_NOTIFICATIONS:
146
        Suppress server setup tips.
147
    SUPPRESS_JOIN_NOTIFICATION_REPLIES:
148
        Hide member join sticker reply buttons
149
    """
150
    SUPPRESS_JOIN_NOTIFICATIONS = 1 << 0
151
    SUPPRESS_PREMIUM_SUBSCRIPTIONS = 1 << 1
152
    SUPPRESS_GUILD_REMINDER_NOTIFICATIONS = 1 << 2
153
    SUPPRESS_JOIN_NOTIFICATION_REPLIES = 1 << 3
154
155
156
@dataclass
0 ignored issues
show
best-practice introduced by
Too many instance attributes (10/7)
Loading history...
157
class GuildPreview(APIObject):
158
    """Represents a guild preview.
159
    Attributes
160
    ----------
161
    id: :class:`Snowflake`
162
        The guild ID.
163
    name: :class:`str`
164
        The guild name.
165
    icon: :class:`str`
166
        The guild icon hash.
167
    splash: :class:`str`
168
        The guild splash hash.
169
    discovery_splash: :class:`str`
170
        The guild discovery splash hash.
171
    emojis: :class:`List[Emoji]`
172
        The guild emojis.
173
    features: :class:`List[GuildFeature]`
174
        The guild features.
175
    approximate_member_count: :class:`int`
176
        The approximate member count.
177
    approximate_presence_count: :class:`int`
178
        The approximate number of online members in this guild
179
    description: :class:`str`
180
        The guild description.
181
    """
182
    id: Snowflake
183
    name: str
184
    emojis: List[Emoji]
185
    features: List[GuildFeature]
186
    approximate_member_count: int
187
    approximate_presence_count: int
188
189
    icon: APINullable[str] = MISSING
190
    splash: APINullable[str] = MISSING
191
    discovery_splash: APINullable[str] = MISSING
192
    description: APINullable[str] = MISSING
193
194
195
@dataclass
0 ignored issues
show
best-practice introduced by
Too many instance attributes (59/7)
Loading history...
196
class Guild(APIObject):
197
    """Represents a Discord guild/server in which your client resides.
198
    Attributes
199
    ----------
200
    afk_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
201
        Id of afk channel
202
    afk_timeout: :class:`int`
203
        Afk timeout in seconds
204
    application_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
205
        Application id of the guild creator if it is bot-created
206
    banner: Optional[:class:`str`]
207
        Banner hash
208
    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...
209
        Default message notifications level
210
    description: Optional[:class:`str`]
211
        The description of a Community guild
212
    discovery_splash: Optional[:class:`str`]
213
        Discovery splash hash;
214
        only present for guilds with the "DISCOVERABLE" feature
215
    emojis: List[:class:`~pincer.objects.message.emoji.Emoji`]
216
        Custom guild emojis
217
    explicit_content_filter: :class:`~pincer.objects.guild.guild.ExplicitContentFilterLevel`
218
        Explicit content filter level
219
    features: List[:class:`~pincer.objects.guild.features.GuildFeature`]
220
        Enabled guild features
221
    id: :class:`~pincer.utils.snowflake.Snowflake`
222
        Guild id
223
    icon: Optional[:class:`str`]
224
        Icon hash
225
    mfa_level: :class:`~pincer.objects.guild.guild.MFALevel`
226
        Required MFA level for the guild
227
    name: :class:`str`
228
        Guild name (2-100 characters, excluding trailing and leading
229
        whitespace)
230
    nsfw_level: :class:`~pincer.objects.guild.guild.NSFWLevel`
231
        Guild NSFW level
232
    owner_id: :class:`~pincer.utils.snowflake.Snowflake`
233
        Id of owner
234
    preferred_locale: :class:`str`
235
        The preferred locale of a Community guild;
236
        used in server discovery and notices from Discord;
237
        defaults to "en-US"
238
    premium_tier: :class:`~pincer.objects.guild.guild.PremiumTier`
239
        Premium tier (Server Boost level)
240
    public_updates_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
241
        The id of the channel where admins
242
        and moderators of Community guilds receive notices from Discord
243
    roles: List[:class:`~pincer.objects.guild.role.Role`]
244
        Roles in the guild
245
    rules_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
246
        The id of the channel where Community guilds can display rules
247
        and/or guidelines
248
    splash: Optional[:class:`str`]
249
        Splash hash
250
    system_channel_flags: :class:`~pincer.objects.guild.guild.SystemChannelFlags`
251
        System channel flags
252
    system_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
253
        The id of the channel where guild notices
254
        such as welcome messages and boost events are posted
255
    vanity_url_code: Optional[:class:`str`]
256
        The vanity url code for the guild
257
    verification_level: :class:`~pincer.objects.guild.guild.VerificationLevel`
258
        Verification level required for the guild
259
    approximate_member_count: APINullable[:class:`int`]
260
        Approximate number of members in this guild, returned from the
261
        `GET /guilds/<id>` endpoint when with_counts is true
262
    approximate_presence_count: APINullable[:class:`int`]
263
        Approximate number of non-offline members in this guild,
264
        returned from the `GET /guilds/<id>`
265
        endpoint when with_counts is true
266
    channels: APINullable[List[:class:`~pincer.objects.guild.channel.Channel`]]
267
        Channels in the guild
268
    icon_hash: APINullable[Optional[:class:`str`]]
269
        Icon hash, returned when in the template object
270
    joined_at: APINullable[:class:`~pincer.utils.timestamp.Timestamp`]
271
        When this guild was joined at
272
    large: APINullable[:class:`bool`]
273
        True if this is considered a large guild
274
    max_members: APINullable[:class:`int`]
275
        The maximum number of members for the guild
276
    max_presences: APINullable[Optional[:class:`int`]]
277
        The maximum number of presences for the guild
278
        (null is always returned, apart from the largest of guilds)
279
    max_video_channel_users: APINullable[:class:`int`]
280
        The maximum amount of users in a video channel
281
    members: APINullable[List[:class:`~pincer.objects.guild.member.GuildMember`]]
282
        Users in the guild
283
    member_count: APINullable[:class:`bool`]
284
        Total number of members in this guild
285
    nsfw: APINullable[:class:`bool`]
286
        Boolean if the server is NSFW
287
    owner: APINullable[:class:`bool`]
288
        True if the user is the owner of the guild
289
    permissions: APINullable[:class:`str`]
290
        Total permissions for the user in the guild
291
        (excludes overwrites)
292
    premium_subscription_count: APINullable[:class:`int`]
293
        The number of boosts this guild currently has
294
    presences: APINullable[List[:class:`~pincer.objects.events.presence.PresenceUpdateEvent`]]
295
        Presences of the members in the guild,
296
        will only include non-offline members if the size is greater
297
        than large threshold
298
    stage_instances: APINullable[List[:class:`~pincer.objects.guild.stage.StageInstance`]]
299
        Stage instances in the guild
300
    stickers: Optional[List[:class:`~pincer.objects.message.sticker.Sticker`]]
301
        Custom guild stickers
302
    region: APINullable[Optional[:class:`str`]]
303
        Voice region id for the guild (deprecated)
304
    threads: APINullable[List[:class:`~pincer.objects.guild.channel.Channel`]]
305
        All active threads in the guild that current user
306
        has permission to view
307
    unavailable: APINullable[:class:`bool`]
308
        True if this guild is unavailable due to an outage
309
    voice_states: APINullable[List[:class:`~pincer.objects.user.voice_state.VoiceState`]]
310
        States of members currently in voice channels;
311
        lacks the guild_id key
312
    widget_enabled: APINullable[:class:`bool`]
313
        True if the server widget is enabled
314
    widget_channel_id: APINullable[Optional[:class:`~pincer.utils.snowflake.Snowflake`]]
315
        The channel id that the widget will generate an invite to,
316
        or null if set to no invite
317
    welcome_screen: APINullable[:class:`~pincer.objects.guild.welcome_screen.WelcomeScreen`]
318
        The welcome screen of a Community guild, shown to new members,
319
        returned in an Invite's guild object
320
    """
321
    # noqa: E501
322
    afk_timeout: int
323
    default_message_notifications: DefaultMessageNotificationLevel
324
    emojis: List[Emoji]
325
    explicit_content_filter: ExplicitContentFilterLevel
326
    features: List[GuildFeature]
327
    id: Snowflake
328
    mfa_level: MFALevel
329
    name: str
330
    nsfw_level: GuildNSFWLevel
331
    owner_id: Snowflake
332
    preferred_locale: str
333
    premium_tier: PremiumTier
334
    roles: List[Role]
335
    system_channel_flags: SystemChannelFlags
336
    verification_level: VerificationLevel
337
338
    guild_scheduled_events: APINullable[List] = MISSING
339
    lazy: APINullable[bool] = MISSING
340
    premium_progress_bar_enabled: APINullable[bool] = MISSING
341
    guild_hashes: APINullable[Dict] = MISSING
342
    afk_channel_id: APINullable[Snowflake] = MISSING
343
    application_id: APINullable[Snowflake] = MISSING
344
    embedded_activities: APINullable[List] = MISSING
345
    banner: APINullable[str] = MISSING
346
    description: APINullable[str] = MISSING
347
    discovery_splash: APINullable[str] = MISSING
348
    icon: APINullable[str] = MISSING
349
    public_updates_channel_id: APINullable[Snowflake] = MISSING
350
    rules_channel_id: APINullable[Snowflake] = MISSING
351
    splash: APINullable[str] = MISSING
352
    system_channel_id: APINullable[Snowflake] = MISSING
353
    vanity_url_code: APINullable[str] = MISSING
354
355
    application_command_counts: APINullable[Dict] = MISSING
356
    application_command_count: APINullable[int] = MISSING
357
    approximate_member_count: APINullable[int] = MISSING
358
    approximate_presence_count: APINullable[int] = MISSING
359
    channels: APINullable[List[Channel]] = field(default_factory=list)
360
    # 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...
361
    hub_type: APINullable[Any] = MISSING
362
    icon_hash: APINullable[Optional[str]] = MISSING
363
    joined_at: APINullable[Timestamp] = MISSING
364
    large: APINullable[bool] = MISSING
365
    max_members: APINullable[int] = MISSING
366
    max_presences: APINullable[Optional[int]] = MISSING
367
    max_video_channel_users: APINullable[int] = MISSING
368
    members: APINullable[List[GuildMember]] = MISSING
369
    member_count: APINullable[bool] = MISSING
370
    nsfw: APINullable[bool] = MISSING
371
    # Note: This is missing from discord's docs but in the api
372
    owner: APINullable[bool] = MISSING
373
    permissions: APINullable[str] = MISSING
374
    premium_subscription_count: APINullable[int] = MISSING
375
    presences: APINullable[List[PresenceUpdateEvent]] = MISSING
376
    stage_instances: APINullable[List[StageInstance]] = MISSING
377
    stickers: APINullable[List[Sticker]] = MISSING
378
    region: APINullable[Optional[str]] = MISSING
379
    threads: APINullable[List[Channel]] = MISSING
380
    # Guilds are considered available unless otherwise specified
381
    unavailable: APINullable[bool] = False
382
    voice_states: APINullable[List[VoiceState]] = MISSING
383
    widget_enabled: APINullable[bool] = MISSING
384
    widget_channel_id: APINullable[Optional[Snowflake]] = MISSING
385
    welcome_screen: APINullable[WelcomeScreen] = MISSING
386
387
    @classmethod
388
    async def from_id(cls, client: Client, _id: Union[int, Snowflake]) -> Guild:
389
        """
390
        Parameters
391
        ----------
392
        client : `~pincer.Client`
393
            Client object to use the http gateway from.
394
        _id : :class: `pincer.utils.snowflake.Snowflake`
395
            Guild ID.
396
        Returns
397
        -------
398
        :class: `~pincer.objects.guild.guild.Guild`
399
            The new guild object.
400
        """
401
        data = await client.http.get(f"/guilds/{_id}")
402
        channel_data = await client.http.get(f"/guilds/{_id}/channels")
403
404
        data["channels"]: List[Channel] = [
405
            Channel.from_dict({**i, "_client": client, "_http": client.http})
406
            for i in (channel_data or [])
407
        ]
408
409
        return Guild.from_dict(construct_client_dict(client, data))
410
411
    async def get_member(self, _id: int) -> GuildMember:
412
        """|coro|
413
        Fetches a GuildMember from its identifier
414
        Parameters
415
        ----------
416
        _id:
417
            The id of the guild member which should be fetched from the Discord
418
            gateway.
419
        Returns
420
        -------
421
        :class:`~pincer.objects.guild.member.GuildMember`
422
            A GuildMember object.
423
        """
424
        return await GuildMember.from_id(self._client, self.id, _id)
425
426
    @overload
427
    async def modify_member(
428
            self, *,
429
            _id: int,
430
            nick: Optional[str] = None,
431
            roles: Optional[List[Snowflake]] = None,
432
            mute: Optional[bool] = None,
433
            deaf: Optional[bool] = None,
434
            channel_id: Optional[Snowflake] = None
435
    ) -> GuildMember:
436
        """|coro|
437
        Modifies a member in the guild from its identifier and based on the
438
        keyword arguments provided.
439
        Parameters
440
        ----------
441
        _id : int
442
            Id of the member to modify
443
        nick : Optional[:class:`str`]
444
            New nickname for the member |default| :data:`None`
445
        roles : Optional[List[:class:`~pincer.utils.snowflake.Snowflake]]
446
            New roles for the member |default| :data:`None`
447
        mute : Optional[:class:`bool`]
448
            Whether the member is muted |default| :data:`None`
449
        deaf : Optional[:class:`bool`]
450
            Whether the member is deafened |default| :data:`None`
451
        channel_id : Optional[:class:`~pincer.utils.snowflake.Snowflake]
452
            Voice channel id to move to |default| :data:`None`
453
        Returns
454
        -------
455
        :class:`~pincer.objects.guild.member.GuildMember`
456
            The new member object.
457
        """
458
        ...
459
460
    async def modify_member(self, _id: int, **kwargs) -> GuildMember:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
461
        data = await self._http.patch(
462
            f"guilds/{self.id}/members/{_id}",
463
            data=kwargs
464
        )
465
        return GuildMember.from_dict(construct_client_dict(self._client, data))
466
467
    async def ban(self, member_id: int, **kwargs):
468
        """|coro|
469
        Bans a guild member.
470
        Parameters
471
        ----------
472
        member_id : :class: int
473
            ID of the guild member to ban.
474
        \\*\\* kwargs
475
            Additional keyword arguments to ban the guild member with.
476
        """
477
        await self._http.put(f"/guilds/{self.id}/bans/{member_id}", data=kwargs)
478
479
    async def kick(self, member_id: int):
480
        """|coro|
481
        Kicks a guild member.
482
        Parameters
483
        ----------
484
        member_id : :class: int
485
            ID of the guild member to kick.
486
        """
487
        await self._http.delete(f"/guilds/{self.id}/members/{member_id}")
488
489
    async def edit(self, **kwargs):
490
        """|coro|
491
        Modifies the guild.
492
        Parameters
493
        ----------
494
        \\*\\* kwargs
495
            Keyword arguments to modify the guild with.
496
        """
497
        await self._http.patch(f"/guilds/{self.id}", data=kwargs)
498
499
    async def preview(self) -> GuildPreview:
500
        """|coro|
501
        Previews the guild.
502
        Returns
503
        -------
504
        :class:`~pincer.objects.guild.guild.GuildPreview`
505
            The guild preview object.
506
        """
507
        data = await self._http.get(f"/guilds/{self.id}/preview")
508
        return GuildPreview.from_dict(data)
509
510
    async def delete(self):
511
        """|coro|
512
        Deletes the guild. Returns `204 No Content` on success.
513
        """
514
        await self._http.delete(f"/guilds/{self.id}")
515
516
    @classmethod
517
    def from_dict(cls, data) -> Guild:
518
        """
519
        Parameters
520
        ----------
521
        data : :class: Dict
522
            Guild data received from the discord API.
523
        Returns
524
        -------
525
        :class: `~pincer.objects.guild.guild.Guild`
526
            The new guild object.
527
        Raises
528
        :class: `~pincer.exceptions.UnavailableGuildError`
529
            The guild is unavailable due to a discord outage.
530
        """
531
        if data.get("unavailable", False):
532
            raise UnavailableGuildError(
533
                f"Guild \"{data['id']}\" is unavailable due to a discord"
534
                " outage."
535
            )
536
537
        return super().from_dict(data)
538
539
540
@dataclass
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
541
class UnavailableGuild(APIObject):
542
    id: Snowflake
543
    unavailable: bool = True
0 ignored issues
show
Coding Style introduced by
Final newline missing
Loading history...