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

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

Complexity

Conditions 1

Size

Total Lines 14
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 14
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...
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
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
@dataclass
0 ignored issues
show
best-practice introduced by
Too many instance attributes (10/7)
Loading history...
156
class GuildPreview(APIObject):
157
    """Represents a guild preview.
158
    Attributes
159
    ----------
160
    id: :class:`Snowflake`
161
        The guild ID.
162
    name: :class:`str`
163
        The guild name.
164
    icon: :class:`str`
165
        The guild icon hash.
166
    splash: :class:`str`
167
        The guild splash hash.
168
    discovery_splash: :class:`str`
169
        The guild discovery splash hash.
170
    emojis: :class:`List[Emoji]`
171
        The guild emojis.
172
    features: :class:`List[GuildFeature]`
173
        The guild features.
174
    approximate_member_count: :class:`int`
175
        The approximate member count.
176
    approximate_presence_count: :class:`int`
177
        The approximate number of online members in this guild
178
    description: :class:`str`
179
        The guild description.
180
    """
181
    id: Snowflake
182
    name: str
183
    emojis: List[Emoji]
184
    features: List[GuildFeature]
185
    approximate_member_count: int
186
    approximate_presence_count: int
187
188
    icon: APINullable[str] = MISSING
189
    splash: APINullable[str] = MISSING
190
    discovery_splash: APINullable[str] = MISSING
191
    description: APINullable[str] = MISSING
192
193
@dataclass
0 ignored issues
show
best-practice introduced by
Too many instance attributes (59/7)
Loading history...
194
class Guild(APIObject):
195
    """Represents a Discord guild/server in which your client resides.
196
    Attributes
197
    ----------
198
    afk_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
199
        Id of afk channel
200
    afk_timeout: :class:`int`
201
        Afk timeout in seconds
202
    application_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
203
        Application id of the guild creator if it is bot-created
204
    banner: Optional[:class:`str`]
205
        Banner hash
206
    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...
207
        Default message notifications level
208
    description: Optional[:class:`str`]
209
        The description of a Community guild
210
    discovery_splash: Optional[:class:`str`]
211
        Discovery splash hash;
212
        only present for guilds with the "DISCOVERABLE" feature
213
    emojis: List[:class:`~pincer.objects.message.emoji.Emoji`]
214
        Custom guild emojis
215
    explicit_content_filter: :class:`~pincer.objects.guild.guild.ExplicitContentFilterLevel`
216
        Explicit content filter level
217
    features: List[:class:`~pincer.objects.guild.features.GuildFeature`]
218
        Enabled guild features
219
    id: :class:`~pincer.utils.snowflake.Snowflake`
220
        Guild id
221
    icon: Optional[:class:`str`]
222
        Icon hash
223
    mfa_level: :class:`~pincer.objects.guild.guild.MFALevel`
224
        Required MFA level for the guild
225
    name: :class:`str`
226
        Guild name (2-100 characters, excluding trailing and leading
227
        whitespace)
228
    nsfw_level: :class:`~pincer.objects.guild.guild.NSFWLevel`
229
        Guild NSFW level
230
    owner_id: :class:`~pincer.utils.snowflake.Snowflake`
231
        Id of owner
232
    preferred_locale: :class:`str`
233
        The preferred locale of a Community guild;
234
        used in server discovery and notices from Discord;
235
        defaults to "en-US"
236
    premium_tier: :class:`~pincer.objects.guild.guild.PremiumTier`
237
        Premium tier (Server Boost level)
238
    public_updates_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
239
        The id of the channel where admins
240
        and moderators of Community guilds receive notices from Discord
241
    roles: List[:class:`~pincer.objects.guild.role.Role`]
242
        Roles in the guild
243
    rules_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
244
        The id of the channel where Community guilds can display rules
245
        and/or guidelines
246
    splash: Optional[:class:`str`]
247
        Splash hash
248
    system_channel_flags: :class:`~pincer.objects.guild.guild.SystemChannelFlags`
249
        System channel flags
250
    system_channel_id: Optional[:class:`~pincer.utils.snowflake.Snowflake`]
251
        The id of the channel where guild notices
252
        such as welcome messages and boost events are posted
253
    vanity_url_code: Optional[:class:`str`]
254
        The vanity url code for the guild
255
    verification_level: :class:`~pincer.objects.guild.guild.VerificationLevel`
256
        Verification level required for the guild
257
    approximate_member_count: APINullable[:class:`int`]
258
        Approximate number of members in this guild, returned from the
259
        `GET /guilds/<id>` endpoint when with_counts is true
260
    approximate_presence_count: APINullable[:class:`int`]
261
        Approximate number of non-offline members in this guild,
262
        returned from the `GET /guilds/<id>`
263
        endpoint when with_counts is true
264
    channels: APINullable[List[:class:`~pincer.objects.guild.channel.Channel`]]
265
        Channels in the guild
266
    icon_hash: APINullable[Optional[:class:`str`]]
267
        Icon hash, returned when in the template object
268
    joined_at: APINullable[:class:`~pincer.utils.timestamp.Timestamp`]
269
        When this guild was joined at
270
    large: APINullable[:class:`bool`]
271
        True if this is considered a large guild
272
    max_members: APINullable[:class:`int`]
273
        The maximum number of members for the guild
274
    max_presences: APINullable[Optional[:class:`int`]]
275
        The maximum number of presences for the guild
276
        (null is always returned, apart from the largest of guilds)
277
    max_video_channel_users: APINullable[:class:`int`]
278
        The maximum amount of users in a video channel
279
    members: APINullable[List[:class:`~pincer.objects.guild.member.GuildMember`]]
280
        Users in the guild
281
    member_count: APINullable[:class:`bool`]
282
        Total number of members in this guild
283
    nsfw: APINullable[:class:`bool`]
284
        Boolean if the server is NSFW
285
    owner: APINullable[:class:`bool`]
286
        True if the user is the owner of the guild
287
    permissions: APINullable[:class:`str`]
288
        Total permissions for the user in the guild
289
        (excludes overwrites)
290
    premium_subscription_count: APINullable[:class:`int`]
291
        The number of boosts this guild currently has
292
    presences: APINullable[List[:class:`~pincer.objects.events.presence.PresenceUpdateEvent`]]
293
        Presences of the members in the guild,
294
        will only include non-offline members if the size is greater
295
        than large threshold
296
    stage_instances: APINullable[List[:class:`~pincer.objects.guild.stage.StageInstance`]]
297
        Stage instances in the guild
298
    stickers: Optional[List[:class:`~pincer.objects.message.sticker.Sticker`]]
299
        Custom guild stickers
300
    region: APINullable[Optional[:class:`str`]]
301
        Voice region id for the guild (deprecated)
302
    threads: APINullable[List[:class:`~pincer.objects.guild.channel.Channel`]]
303
        All active threads in the guild that current user
304
        has permission to view
305
    unavailable: APINullable[:class:`bool`]
306
        True if this guild is unavailable due to an outage
307
    voice_states: APINullable[List[:class:`~pincer.objects.user.voice_state.VoiceState`]]
308
        States of members currently in voice channels;
309
        lacks the guild_id key
310
    widget_enabled: APINullable[:class:`bool`]
311
        True if the server widget is enabled
312
    widget_channel_id: APINullable[Optional[:class:`~pincer.utils.snowflake.Snowflake`]]
313
        The channel id that the widget will generate an invite to,
314
        or null if set to no invite
315
    welcome_screen: APINullable[:class:`~pincer.objects.guild.welcome_screen.WelcomeScreen`]
316
        The welcome screen of a Community guild, shown to new members,
317
        returned in an Invite's guild object
318
    """
319
    # noqa: E501
320
    afk_timeout: int
321
    default_message_notifications: DefaultMessageNotificationLevel
322
    emojis: List[Emoji]
323
    explicit_content_filter: ExplicitContentFilterLevel
324
    features: List[GuildFeature]
325
    id: Snowflake
326
    mfa_level: MFALevel
327
    name: str
328
    nsfw_level: GuildNSFWLevel
329
    owner_id: Snowflake
330
    preferred_locale: str
331
    premium_tier: PremiumTier
332
    roles: List[Role]
333
    system_channel_flags: SystemChannelFlags
334
    verification_level: VerificationLevel
335
336
    guild_scheduled_events: APINullable[List] = MISSING
337
    lazy: APINullable[bool] = MISSING
338
    premium_progress_bar_enabled: APINullable[bool] = MISSING
339
    guild_hashes: APINullable[Dict] = MISSING
340
    afk_channel_id: APINullable[Snowflake] = MISSING
341
    application_id: APINullable[Snowflake] = MISSING
342
    embedded_activities: APINullable[List] = MISSING
343
    banner: APINullable[str] = MISSING
344
    description: APINullable[str] = MISSING
345
    discovery_splash: APINullable[str] = MISSING
346
    icon: APINullable[str] = MISSING
347
    public_updates_channel_id: APINullable[Snowflake] = MISSING
348
    rules_channel_id: APINullable[Snowflake] = MISSING
349
    splash: APINullable[str] = MISSING
350
    system_channel_id: APINullable[Snowflake] = MISSING
351
    vanity_url_code: APINullable[str] = MISSING
352
353
    application_command_counts: APINullable[Dict] = MISSING
354
    application_command_count: APINullable[int] = MISSING
355
    approximate_member_count: APINullable[int] = MISSING
356
    approximate_presence_count: APINullable[int] = MISSING
357
    channels: APINullable[List[Channel]] = field(default_factory=list)
358
    # 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...
359
    hub_type: APINullable[Any] = MISSING
360
    icon_hash: APINullable[Optional[str]] = MISSING
361
    joined_at: APINullable[Timestamp] = MISSING
362
    large: APINullable[bool] = MISSING
363
    max_members: APINullable[int] = MISSING
364
    max_presences: APINullable[Optional[int]] = MISSING
365
    max_video_channel_users: APINullable[int] = MISSING
366
    members: APINullable[List[GuildMember]] = MISSING
367
    member_count: APINullable[bool] = MISSING
368
    nsfw: APINullable[bool] = MISSING
369
    # Note: This is missing from discord's docs but in the api
370
    owner: APINullable[bool] = MISSING
371
    permissions: APINullable[str] = MISSING
372
    premium_subscription_count: APINullable[int] = MISSING
373
    presences: APINullable[List[PresenceUpdateEvent]] = MISSING
374
    stage_instances: APINullable[List[StageInstance]] = MISSING
375
    stickers: APINullable[List[Sticker]] = MISSING
376
    region: APINullable[Optional[str]] = MISSING
377
    threads: APINullable[List[Channel]] = MISSING
378
    # Guilds are considered available unless otherwise specified
379
    unavailable: APINullable[bool] = False
380
    voice_states: APINullable[List[VoiceState]] = MISSING
381
    widget_enabled: APINullable[bool] = MISSING
382
    widget_channel_id: APINullable[Optional[Snowflake]] = MISSING
383
    welcome_screen: APINullable[WelcomeScreen] = MISSING
384
385
    @classmethod
386
    async def from_id(cls, client: Client, _id: Union[int, Snowflake]) -> Guild:
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'Union'
Loading history...
387
        """
388
        Parameters
389
        ----------
390
        client : `~pincer.Client`
391
            Client object to use the http gateway from.
392
        _id : :class: `pincer.utils.snowflake.Snowflake`
393
            Guild ID.
394
        Returns
395
        -------
396
        :class: `~pincer.objects.guild.guild.Guild`
397
            The new guild object.
398
        """
399
        data = await client.http.get(f"/guilds/{_id}")
400
        channel_data = await client.http.get(f"/guilds/{_id}/channels")
401
402
        data["channels"]: List[Channel] = [
403
            Channel.from_dict({**i, "_client": client, "_http": client.http})
404
            for i in (channel_data or [])
405
        ]
406
407
        return Guild.from_dict(construct_client_dict(client, data))
408
409
    async def get_member(self, _id: int) -> GuildMember:
410
        """|coro|
411
        Fetches a GuildMember from its identifier
412
        Parameters
413
        ----------
414
        _id:
415
            The id of the guild member which should be fetched from the Discord
416
            gateway.
417
        Returns
418
        -------
419
        :class:`~pincer.objects.guild.member.GuildMember`
420
            A GuildMember object.
421
        """
422
        return await GuildMember.from_id(self._client, self.id, _id)
423
424
    @overload
425
    async def modify_member(
426
            self, *,
427
            _id: int,
428
            nick: Optional[str] = None,
429
            roles: Optional[List[Snowflake]] = None,
430
            mute: Optional[bool] = None,
431
            deaf: Optional[bool] = None,
432
            channel_id: Optional[Snowflake] = None
433
    ) -> GuildMember:
434
        """|coro|
435
        Modifies a member in the guild from its identifier and based on the
436
        keyword arguments provided.
437
        Parameters
438
        ----------
439
        _id : int
440
            Id of the member to modify
441
        nick : Optional[:class:`str`]
442
            New nickname for the member |default| :data:`None`
443
        roles : Optional[List[:class:`~pincer.utils.snowflake.Snowflake]]
444
            New roles for the member |default| :data:`None`
445
        mute : Optional[:class:`bool`]
446
            Whether the member is muted |default| :data:`None`
447
        deaf : Optional[:class:`bool`]
448
            Whether the member is deafened |default| :data:`None`
449
        channel_id : Optional[:class:`~pincer.utils.snowflake.Snowflake]
450
            Voice channel id to move to |default| :data:`None`
451
        Returns
452
        -------
453
        :class:`~pincer.objects.guild.member.GuildMember`
454
            The new member object.
455
        """
456
        ...
457
458
    async def modify_member(self, _id: int, **kwargs) -> GuildMember:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
459
        data = await self._http.patch(
460
            f"guilds/{self.id}/members/{_id}",
461
            data=kwargs
462
        )
463
        return GuildMember.from_dict(construct_client_dict(self._client, data))
464
465
    async def ban(self, member_id: int, **kwargs):
466
        """|coro|
467
        Bans a guild member.
468
        Parameters
469
        ----------
470
        member_id : :class: int
471
            ID of the guild member to ban.
472
        \\*\\* kwargs
473
            Additional keyword arguments to ban the guild member with.
474
        """
475
        await self._http.put(f"/guilds/{self.id}/bans/{member_id}", data=kwargs)
476
477
    async def kick(self, member_id: int):
478
        """|coro|
479
        Kicks a guild member.
480
        Parameters
481
        ----------
482
        member_id : :class: int
483
            ID of the guild member to kick.
484
        """
485
        await self._http.delete(f"/guilds/{self.id}/members/{member_id}")
486
487
    async def edit(self, **kwargs):
488
        """|coro|
489
        Modifies the guild.
490
        Parameters
491
        ----------
492
        \\*\\* kwargs
493
            Keyword arguments to modify the guild with.
494
        """
495
        await self._http.patch(f"/guilds/{self.id}", data=kwargs)
496
497
    async def preview(self) -> GuildPreview:
498
        """|coro|
499
        Previews the guild.
500
        Returns
501
        -------
502
        :class:`~pincer.objects.guild.guild.GuildPreview`
503
            The guild preview object.
504
        """
505
        data = await self._http.get(f"/guilds/{self.id}/preview")
506
        return GuildPreview.from_dict(data)
507
508
    async def delete(self):
509
        """|coro|
510
        Deletes the guild. Returns `204 No Content` on success.
511
        """
512
        await self._http.delete(f"/guilds/{self.id}")
513
514
    @classmethod
515
    def from_dict(cls, data) -> Guild:
516
        """
517
        Parameters
518
        ----------
519
        data : :class: Dict
520
            Guild data received from the discord API.
521
        Returns
522
        -------
523
        :class: `~pincer.objects.guild.guild.Guild`
524
            The new guild object.
525
        Raises
526
        :class: `~pincer.exceptions.UnavailableGuildError`
527
            The guild is unavailable due to a discord outage.
528
        """
529
        if data.get("unavailable", False):
530
            raise UnavailableGuildError(
531
                f"Guild \"{data['id']}\" is unavailable due to a discord"
532
                " outage."
533
            )
534
535
        return super().from_dict(data)
536
537
538
@dataclass
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
539
class UnavailableGuild(APIObject):
540
    id: Snowflake
541
    unavailable: bool = True
0 ignored issues
show
Coding Style introduced by
Final newline missing
Loading history...