Passed
Push — main ( 6c0406...945e5e )
by
unknown
01:36 queued 12s
created

pincer.client.Client.__init__()   A

Complexity

Conditions 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 13
rs 10
c 0
b 0
f 0
cc 1
nop 2
1
# -*- coding: utf-8 -*-
0 ignored issues
show
introduced by
Missing module docstring
Loading history...
2
# MIT License
3
#
4
# Copyright (c) 2021 Pincer
5
#
6
# Permission is hereby granted, free of charge, to any person obtaining
7
# a copy of this software and associated documentation files
8
# (the "Software"), to deal in the Software without restriction,
9
# including without limitation the rights to use, copy, modify, merge,
10
# publish, distribute, sublicense, and/or sell copies of the Software,
11
# and to permit persons to whom the Software is furnished to do so,
12
# subject to the following conditions:
13
#
14
# The above copyright notice and this permission notice shall be
15
# included in all copies or substantial portions of the Software.
16
#
17
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
import logging
25
from asyncio import iscoroutinefunction
26
from inspect import getcallargs, getfullargspec
0 ignored issues
show
Unused Code introduced by
Unused getcallargs imported from inspect
Loading history...
27
from typing import Optional, TypeVar, Callable, Coroutine, Any, Union
28
29
from pincer import __package__
1 ignored issue
show
Bug Best Practice introduced by
This seems to re-define the built-in __package__.

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

Loading history...
30
from pincer._config import GatewayConfig
31
from pincer.core.dispatch import GatewayDispatch
32
from pincer.core.gateway import Dispatcher
33
from pincer.core.http import HTTPClient
34
from pincer.exceptions import InvalidEventName
35
from pincer.objects.user import User
36
37
_log = logging.getLogger(__package__)
38
39
Coro = TypeVar('Coro', bound=Callable[..., Coroutine[Any, Any, Any]])
40
41
_events = {
42
    "ready": "on_ready",
43
    "on_ready": None,
44
    "channel_create": "on_channel_create",
45
    "on_channel_create": None,
46
    "channel_update": "on_channel_update",
47
    "on_channel_update": None,
48
    "channel_delete": "on_channel_delete",
49
    "on_channel_delete": None,
50
    "channel_pin_update": "on_channel_pin_update",
51
    "on_channel_pin_update": None,
52
    "thread_create": "on_thread_create",
53
    "on_thread_create": None,
54
    "thread_update": "on_thread_update",
55
    "on_thread_update": None,
56
    "thread_delete": "on_thread_delete",
57
    "on_thread_delete": None,
58
    "thread_member_update": "on_thread_member_update",
59
    "on_thread_member_update": None,
60
    "thread_members_update": "on_thread_members_update",
61
    "on_thread_members_update": None,
62
    "guild_create": "on_guild_create",
63
    "on_guild_create": None,
64
    "guild_update": "on_guild_update",
65
    "on_guild_update": None,
66
    "guild_delete": "on_guild_delete",
67
    "on_guild_delete": None,
68
    "guild_ban_add": "on_guild_ban_add",
69
    "on_guild_ban_add": None,
70
    "guild_ban_remove": "on_guild_ban_remove",
71
    "on_guild_ban_remove": None,
72
    "guild_emoji_update": "on_guild_emoji_update",
73
    "on_guild_emoji_update": None,
74
    "guild_stickers_update": "on_guild_stickers_update",
75
    "on_guild_stickers_update": None,
76
    "guild_integrations_update": "on_guild_integrations_update",
77
    "on_guild_integrations_update": None,
78
    "guild_member_add": "on_guild_member_add",
79
    "on_guild_member_add": None,
80
    "guild_member_remove": "on_guild_member_remove",
81
    "on_guild_member_remove": None,
82
    "guild_members_chunk": "on_guild_members_chunk",
83
    "on_guild_members_chunk": None,
84
    "guild_role_create": "on_guild_role_create",
85
    "on_guild_role_create": None,
86
    "guild_role_update": "on_guild_role_update",
87
    "on_guild_role_update": None,
88
    "guild_role_delete": "on_guild_role_delete",
89
    "on_guild_role_delete": None,
90
    "integration_create": "on_integration_create",
91
    "on_integration_create": None,
92
    "integration_update": "on_integration_update",
93
    "on_integration_update": None,
94
    "integration_delete": "on_integration_delete",
95
    "on_integration_delete": None,
96
    "invite_create": "on_invite_create",
97
    "on_invite_create": None,
98
    "messages_create": "on_messages_create",
99
    "on_messages_create": None,
100
    "message_update": "on_message_update",
101
    "on_message_update": None,
102
    "message_delete": "on_message_delete",
103
    "on_message_delete": None,
104
    "message_delete_bulk": "on_message_delete_bulk",
105
    "on_message_delete_bulk": None,
106
    "message_reaction_add": "on_message_reaction_add",
107
    "on_message_reaction_add": None,
108
    "message_reaction_remove": "on_message_reaction_remove",
109
    "on_message_reaction_remove": None,
110
    "message_reaction_remove_all": "on_message_reaction_remove_all",
111
    "on_message_reaction_remove_all": None,
112
    "message_reaction_remove_emoji": "on_message_reaction_remove_emoji",
113
    "on_message_reaction_remove_emoji": None,
114
    "presence_update": "on_presence_update",
115
    "on_presence_update": None,
116
    "stage_instance_create": "on_stage_instance_create",
117
    "on_stage_instance_create": None,
118
    "stage_instance_update": "on_stage_instance_update",
119
    "on_stage_instance_update": None,
120
    "stage_instance_delete": "on_stage_instance_delete",
121
    "on_stage_instance_delete": None,
122
    "typing_start": "on_typing_start",
123
    "on_typing_start": None,
124
    "voice_state_update": "on_voice_state_update",
125
    "on_voice_state_update": None,
126
    "voice_server_update": "on_voice_server_update",
127
    "on_voice_server_update": None,
128
    "webhooks_update": "on_webhooks_update",
129
    "on_webhooks_update": None,
130
}
131
132
133
class Client(Dispatcher):
134
    """
135
    The main instance which the user will interact with.
136
    """
137
138
    def __init__(self, token: str):
139
        # TODO: Write docs
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
140
        # TODO: Implement intents
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
141
        super().__init__(
142
            token,
143
            handlers={
144
                0: self.event_handler
145
            }
146
        )
147
148
        self.http = HTTPClient(token, GatewayConfig.version)
149
        self.bot: Optional[User] = None
150
        _events["ready"] = self.__on_ready
151
152
    @staticmethod
153
    def event(coroutine: Coro):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
154
        if not iscoroutinefunction(coroutine):
155
            raise TypeError("Any event which is registered must be a coroutine "
156
                            "function")
157
158
        name: str = coroutine.__name__.lower()
159
160
        if not name.startswith("on_"):
161
            raise InvalidEventName(
162
                f"The event `{name}` its name must start with `on_`"
163
            )
164
165
        if _events.get(name) is not None:
1 ignored issue
show
Comprehensibility Best Practice introduced by
The variable _events does not seem to be defined.
Loading history...
166
            raise InvalidEventName(
167
                f"The event `{name}` has already been registered or is not "
168
                f"a event name."
169
            )
170
171
        _events[name] = coroutine
172
        return coroutine
173
174
    async def event_handler(self, _, payload: GatewayDispatch):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
175
        middleware: Optional[Union[Coro, str]] = _events.get(
176
            payload.event_name.lower()
177
        )
178
179
        if iscoroutinefunction(middleware):
180
            final_call, params = await middleware(payload)
181
        else:
182
            final_call, params = middleware, dict()
183
184
        final_call: str = final_call
185
        params: dict = params
186
187
        final_call_routine: Optional[Coro] = _events.get(final_call)
188
189
        if iscoroutinefunction(final_call_routine):
190
            kwargs = {}
191
            args = getfullargspec(final_call_routine).args
192
            if len(args) >= 1 and args[0] == "self":
193
                kwargs["self"] = self
194
195
            await final_call_routine(**kwargs)
196
197
    async def __on_ready(self, payload: GatewayDispatch):
198
        self.bot = User.from_dict(payload.data.get("user"))
199
        return "on_ready", dict()
200
201
202
Bot = Client
203