Passed
Pull Request — main (#378)
by Yohann
02:06
created

Permission.allow()   A

Complexity

Conditions 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 11
rs 10
c 0
b 0
f 0
cc 3
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
7
from enum import Enum
8
from typing import Tuple, Optional
9
10
11
class Permissions(Enum):
12
    """
13
    Represents the permissions for a guild.
14
    """
15
    CREATE_INSTANT_INVITE = 1 << 0
16
    KICK_MEMBERS = 1 << 1
17
    BAN_MEMBERS = 1 << 2
18
    ADMINISTRATOR = 1 << 3
19
    MANAGE_CHANNELS = 1 << 4
20
    MANAGE_GUIlD = 1 << 5
21
    ADD_REACTIONS = 1 << 6
22
    VIEW_AUDIT_LOG = 1 << 7
23
    PRIORITY_SPEAKER = 1 << 8
24
    STREAM = 1 << 9
25
    VIEW_CHANNEL = 1 << 10
26
    SEND_MESSAGES = 1 << 11
27
    SEND_TTS_MESSAGES = 1 << 12
28
    MANAGE_MESSAGES = 1 << 13
29
    EMBED_LINKS = 1 << 14
30
    ATTACH_FILES = 1 << 15
31
    READ_MESSAGE_HISTORY = 1 << 16
32
    MENTION_EVERYONE = 1 << 17
33
    USE_EXTERNAL_EMOJIS = 1 << 18
34
    VIEW_GUILD_INSIGHTS = 1 << 19
35
    CONNECT = 1 << 20
36
    SPEAK = 1 << 21
37
    MUTE_MEMBERS = 1 << 22
38
    DEAFEN_MEMBERS = 1 << 23
39
    MOVE_MEMBERS = 1 << 24
40
    USE_VAD = 1 << 25
41
    CHANGE_NICKNAME = 1 << 26
42
    MANAGE_NICKNAMES = 1 << 27
43
    MANAGE_ROLES = 1 << 28
44
    MANAGE_WEBHOOKS = 1 << 29
45
    MANAGE_EMOJIS_AND_STICKERS = 1 << 30
46
    USE_APPLICATION_COMMANDS = 1 << 31
47
    REQUEST_TO_SPEAK = 1 << 32
48
    MANAGE_EVENTS = 1 << 33
49
    MANAGE_THREADS = 1 << 34
50
    CREATE_PUBLIC_THREADS = 1 << 35
51
    CREATE_PRIVATE_THREADS = 1 << 36
52
    USE_EXTERNAL_STICKERS = 1 << 37
53
    SEND_MESSAGES_IN_THREADS = 1 << 38
54
    START_EMBEDDED_ACTIVITIES = 1 << 39
55
    MODERATE_MEMBERS = 1 << 40
56
57
58
@dataclass
59
class Permission:
0 ignored issues
show
best-practice introduced by
Too many instance attributes (41/7)
Loading history...
60
    """
61
    Allows for easier access to the permissions
62
63
    Parameters
64
    ----------
65
    create_instant_invite: :class:`Optional[bool]`
66
        Allows creation of instant invites
67
    kick_members: :class:`Optional[bool]`
68
        Allows kicking members
69
    ban_members: :class:`Optional[bool]`
70
        Allows banning members
71
    administrator: :class:`Optional[bool]`
72
        Allows all permissions and bypasses channel permission overwrites
73
    manage_channels: :class:`Optional[bool]`
74
        Allows management and editing of channels
75
    manage_guild: :class:`Optional[bool]`
76
        Allows management and editing of the guild
77
    add_reactions: :class:`Optional[bool]`
78
        Allows for the addition of reactions to messages
79
    view_audit_log: :class:`Optional[bool]`
80
        Allows for viewing of audit logs
81
    priority_speaker: :class:`Optional[bool]`
82
        Allows for using priority speaker in a voice channel
83
    stream: :class:`Optional[bool]`
84
        Allows the user to go live
85
    view_channel: :class:`Optional[bool]`
86
        Allows guild members to view a channel, which includes reading messages in text channels
87
    send_messages: :class:`Optional[bool]`
88
        Allows for sending messages in a channel (does not allow sending messages in threads)
89
    send_tts_messages: :class:`Optional[bool]`
90
        Allows for sending of tts messages
91
    manage_messages: :class:`Optional[bool]`
92
        Allows for deletion of other users messages
93
    embed_links: :class:`Optional[bool]`
94
        Links sent by users with this permission will be auto-embedded
95
    attach_files: :class:`Optional[bool]`
96
        Allows for uploading images and files
97
    read_message_history: :class:`Optional[bool]`
98
        Allows for reading of message history
99
    mention_everyone: :class:`Optional[bool]`
100
        Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all online users in a channel
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (134/100).

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

Loading history...
101
    use_external_emojis: :class:`Optional[bool]`
102
        Allows the usage of custom emojis from other servers
103
    view_guild_insights: :class:`Optional[bool]`
104
        Allows for viewing of guild insights
105
    connect: :class:`Optional[bool]`
106
        Allows for joining of a voice channel
107
    speak: :class:`Optional[bool]`
108
        Allows for speaking in a voice channel
109
    mute_members: :class:`Optional[bool]`
110
        Allows for muting members in a voice channel
111
    deafen_members: :class:`Optional[bool]`
112
        Allows for deafening of members in a voice channel
113
    move_members: :class:`Optional[bool]`
114
        Allows for moving of members between voice channels
115
    use_vad: :class:`Optional[bool]`
116
        Allows for using voice activity detection in a voice channel
117
    change_nickname: :class:`Optional[bool]`
118
        Allows for modification of own nickname
119
    manage_nicknames: :class:`Optional[bool]`
120
        Allows for modification of other users nicknames
121
    manage_roles: :class:`Optional[bool]`
122
        Allows for management and editing of roles
123
    manage_webhooks: :class:`Optional[bool]`
124
        Allows for management and editing of webhooks
125
    manage_emojis_and_stickers: :class:`Optional[bool]`
126
        Allows for management and editing of emojis and stickers
127
    use_application_commands: :class:`Optional[bool]`
128
        Allows for using application-specific commands
129
    request_to_speak: :class:`Optional[bool]`
130
        Allows for requesting to speak in a voice channel
131
    manage_events: :class:`Optional[bool]`
132
        Allows for management and editing of events
133
    manage_threads: :class:`Optional[bool]`
134
        Allows for management and editing of threads
135
    create_public_threads: :class:`Optional[bool]`
136
        Allows for the creation of public threads
137
    create_private_threads: :class:`Optional[bool]`
138
        Allows for the creation of private threads
139
    use_external_stickers: :class:`Optional[bool]`
140
        Allows for the usage of stickers from other servers
141
    send_messages_in_threads: :class:`Optional[bool]`
142
        Allows for sending messages in threads
143
    start_embedded_activities: :class:`Optional[bool]`
144
        Allows for starting of embedded activities
145
    moderate_members: :class:`Optional[bool]`
146
        Allows for moderation of members in a guild
147
    """
148
149
    create_instant_invite: Optional[bool] = None
150
    kick_members: Optional[bool] = None
151
    ban_members: Optional[bool] = None
152
    administrator: Optional[bool] = None
153
    manage_channels: Optional[bool] = None
154
    manage_guild: Optional[bool] = None
155
    add_reactions: Optional[bool] = None
156
    view_audit_log: Optional[bool] = None
157
    priority_speaker: Optional[bool] = None
158
    stream: Optional[bool] = None
159
    view_channel: Optional[bool] = None
160
    send_messages: Optional[bool] = None
161
    send_tts_messages: Optional[bool] = None
162
    manage_messages: Optional[bool] = None
163
    embed_links: Optional[bool] = None
164
    attach_files: Optional[bool] = None
165
    read_message_history: Optional[bool] = None
166
    mention_everyone: Optional[bool] = None
167
    use_external_emojis: Optional[bool] = None
168
    view_guild_insights: Optional[bool] = None
169
    connect: Optional[bool] = None
170
    speak: Optional[bool] = None
171
    mute_members: Optional[bool] = None
172
    deafen_members: Optional[bool] = None
173
    move_members: Optional[bool] = None
174
    use_vad: Optional[bool] = None
175
    change_nickname: Optional[bool] = None
176
    manage_nicknames: Optional[bool] = None
177
    manage_roles: Optional[bool] = None
178
    manage_webhooks: Optional[bool] = None
179
    manage_emojis_and_stickers: Optional[bool] = None
180
    use_application_commands: Optional[bool] = None
181
    request_to_speak: Optional[bool] = None
182
    manage_events: Optional[bool] = None
183
    manage_threads: Optional[bool] = None
184
    create_public_threads: Optional[bool] = None
185
    create_private_threads: Optional[bool] = None
186
    use_external_stickers: Optional[bool] = None
187
    send_messages_in_threads: Optional[bool] = None
188
    start_embedded_activities: Optional[bool] = None
189
    moderate_members: Optional[bool] = None
190
191
    def __setattr__(self, name: str, value: Optional[bool]) -> None:
192
        if not isinstance(value, bool) and value is not None:
193
            raise ValueError(f"Permission {name!r} must be a boolean or None")
194
        return super().__setattr__(name, value)
195
196
    def __eq__(self, object) -> bool:
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in object.

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

Loading history...
197
        """
198
        Permission equality is determined by comparing the integer values of the permissions
199
        """
200
        if isinstance(object, Permission):
0 ignored issues
show
unused-code introduced by
Unnecessary "elif" after "return"
Loading history...
201
            return self.to_int() == object.to_int()
202
        elif isinstance(object, tuple):
203
            return self.to_int() == object
204
205
        return False
206
207
    @classmethod
208
    def from_int(cls, allow: int, deny: int) -> Permission:
209
        """
210
        Create a Permission object from an integer representation of the permissions (deny and allow)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (101/100).

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

Loading history...
211
212
        Parameters
213
        __________
214
        allow: :class:`int`
215
            The integer representation of the permissions that are allowed
216
        deny: :class:`int`
217
            The integer representation of the permissions that are denied
218
        """
219
        clsobj = cls()
220
221
        for enum in Permissions:
222
            if bool(enum.value & allow):
223
                setattr(clsobj, enum.name.lower(), True)
224
            elif bool(enum.value & deny):
225
                setattr(clsobj, enum.name.lower(), False)
226
            else:
227
                setattr(clsobj, enum.name.lower(), None)
228
229
        return clsobj
230
231
    def to_int(self) -> Tuple[int]:
232
        """
233
        Convert the Permission object to an integer representation of the permissions (deny and allow)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (102/100).

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

Loading history...
234
235
        Returns
236
        _______
237
        :class:`Tuple[int]`
238
            The integer representation of the permissions that are allowed and denied
239
        """
240
        allow = 0
241
        deny = 0
242
        for enum in Permissions:
243
            if getattr(self, enum.name.lower()):
244
                allow |= enum.value
245
            elif getattr(self, enum.name.lower()) is False:
246
                deny |= enum.value
247
248
        return allow, deny
249
250
    @property
251
    def allow(self) -> int:
252
        """
253
        Returns the integer representation of the permissions that are allowed
254
        """
255
        allow = 0
256
        for enum in Permissions:
257
            if getattr(self, enum.name.lower()):
258
                allow |= enum.value
259
260
        return allow
261
262
    @property
263
    def deny(self) -> int:
264
        """
265
        Returns the integer representation of the permissions that are denied
266
        """
267
        deny = 0
268
        for enum in Permissions:
269
            if getattr(self, enum.name.lower()) is False:
270
                deny |= enum.value
271
272
        return deny
273