25
25
from .dispatch import Listener
26
26
from .enums import OpCodeType
27
27
from .error import GatewayException
28
- from .http import HTTPClient
28
+ from .http . client import HTTPClient
29
29
from .models .flags import Intents
30
30
from .models .misc import MISSING
31
31
from .models .presence import ClientPresence
32
32
33
33
log = get_logger ("gateway" )
34
34
35
-
36
35
__all__ = ("_Heartbeat" , "WebSocketClient" )
37
36
38
37
@@ -280,7 +279,7 @@ async def wait_until_ready(self):
280
279
"""Waits for the client to become ready according to the Gateway."""
281
280
await self .ready .wait ()
282
281
283
- def _dispatch_event (self , event : str , data : dict ) -> None :
282
+ def _dispatch_event (self , event : str , data : dict ) -> None : # sourcery no-metrics
284
283
"""
285
284
Dispatches an event from the Gateway.
286
285
@@ -291,97 +290,88 @@ def _dispatch_event(self, event: str, data: dict) -> None:
291
290
"""
292
291
path : str = "interactions"
293
292
path += ".models" if event == "INTERACTION_CREATE" else ".api.models"
294
-
295
- if event != "TYPING_START" :
296
- if event != "INTERACTION_CREATE" :
297
- name : str = event .lower ()
298
- try :
299
- _event_path : list = [section .capitalize () for section in name .split ("_" )]
300
- _name : str = (
301
- _event_path [0 ] if len (_event_path ) < 3 else "" .join (_event_path [:- 1 ])
302
- )
303
- __obj : object = getattr (__import__ (path ), _name )
304
-
305
- if name in {"_create" , "_add" }:
306
- data ["_client" ] = self ._http
307
-
308
- self ._dispatch .dispatch (f"on_{ name } " , __obj (** data )) # noqa
309
- except AttributeError as error :
310
- log .fatal (f"An error occured dispatching { name } : { error } " )
293
+ if event == "INTERACTION_CREATE" :
294
+ if not data .get ("type" ):
295
+ log .warning (
296
+ "Context is being created for the interaction, but no type is specified. Skipping..."
297
+ )
311
298
else :
312
- if not data .get ("type" ):
313
- log .warning (
314
- "Context is being created for the interaction, but no type is specified. Skipping..."
315
- )
316
- else :
317
- _context = self .__contextualize (data )
318
- _name : str = ""
319
- __args : list = [_context ]
320
- __kwargs : dict = {}
321
-
322
- if data ["type" ] == InteractionType .APPLICATION_COMMAND :
323
- _name = f"command_{ _context .data .name } "
324
-
325
- if _context .data ._json .get ("options" ):
326
- for option in _context .data .options :
327
- _type = self .__option_type_context (
328
- _context ,
329
- (
330
- option ["type" ]
331
- if isinstance (option , dict )
332
- else option .type .value
333
- ),
334
- )
335
- if _type :
336
- if isinstance (option , dict ):
337
- _type [option ["value" ]]._client = self ._http
338
- option .update ({"value" : _type [option ["value" ]]})
339
- else :
340
- _type [option .value ]._client = self ._http
341
- option ._json .update ({"value" : _type [option .value ]})
342
- _option = self .__sub_command_context (option , _context )
343
- __kwargs .update (_option )
344
-
345
- self ._dispatch .dispatch ("on_command" , _context )
346
- elif data ["type" ] == InteractionType .MESSAGE_COMPONENT :
347
- _name = f"component_{ _context .data .custom_id } "
348
-
349
- if _context .data ._json .get ("values" ):
350
- __args .append (_context .data .values )
351
-
352
- self ._dispatch .dispatch ("on_component" , _context )
353
- elif data ["type" ] == InteractionType .APPLICATION_COMMAND_AUTOCOMPLETE :
354
- _name = f"autocomplete_{ _context .data .id } "
355
-
356
- if _context .data ._json .get ("options" ):
357
- for option in _context .data .options :
358
- __name , _value = self .__sub_command_context (option , _context )
359
- _name += f"_{ __name } " if __name else ""
360
-
361
- if _value :
362
- __args .append (_value )
363
-
364
- self ._dispatch .dispatch ("on_autocomplete" , _context )
365
- elif data ["type" ] == InteractionType .MODAL_SUBMIT :
366
- _name = f"modal_{ _context .data .custom_id } "
367
-
368
- if _context .data ._json .get ("components" ):
369
- for component in _context .data .components :
370
- if component .get ("components" ):
371
- __args .append (
372
- [_value ["value" ] for _value in component ["components" ]][0 ]
373
- )
299
+ # sourcery skip: extract-method
300
+ _context = self .__contextualize (data )
301
+ _name : str = ""
302
+ __args : list = [_context ]
303
+ __kwargs : dict = {}
304
+
305
+ if data ["type" ] == InteractionType .APPLICATION_COMMAND :
306
+ _name = f"command_{ _context .data .name } "
307
+
308
+ if _context .data ._json .get ("options" ):
309
+ for option in _context .data .options :
310
+ _type = self .__option_type_context (
311
+ _context ,
312
+ (option ["type" ] if isinstance (option , dict ) else option .type .value ),
313
+ )
314
+ if _type :
315
+ if isinstance (option , dict ):
316
+ _type [option ["value" ]]._client = self ._http
317
+ option .update ({"value" : _type [option ["value" ]]})
374
318
else :
375
- __args .append (
376
- [_value .value for _value in component .components ][0 ]
377
- )
378
-
379
- self ._dispatch .dispatch ("on_modal" , _context )
380
-
381
- self ._dispatch .dispatch (_name , * __args , ** __kwargs )
382
- self ._dispatch .dispatch ("on_interaction" , _context )
383
- self ._dispatch .dispatch ("on_interaction_create" , _context )
384
-
319
+ _type [option .value ]._client = self ._http
320
+ option ._json .update ({"value" : _type [option .value ]})
321
+ _option = self .__sub_command_context (option , _context )
322
+ __kwargs .update (_option )
323
+
324
+ self ._dispatch .dispatch ("on_command" , _context )
325
+ elif data ["type" ] == InteractionType .MESSAGE_COMPONENT :
326
+ _name = f"component_{ _context .data .custom_id } "
327
+
328
+ if _context .data ._json .get ("values" ):
329
+ __args .append (_context .data .values )
330
+
331
+ self ._dispatch .dispatch ("on_component" , _context )
332
+ elif data ["type" ] == InteractionType .APPLICATION_COMMAND_AUTOCOMPLETE :
333
+ _name = f"autocomplete_{ _context .data .id } "
334
+
335
+ if _context .data ._json .get ("options" ):
336
+ for option in _context .data .options :
337
+ __name , _value = self .__sub_command_context (option , _context )
338
+ _name += f"_{ __name } " if __name else ""
339
+
340
+ if _value :
341
+ __args .append (_value )
342
+
343
+ self ._dispatch .dispatch ("on_autocomplete" , _context )
344
+ elif data ["type" ] == InteractionType .MODAL_SUBMIT :
345
+ _name = f"modal_{ _context .data .custom_id } "
346
+
347
+ if _context .data ._json .get ("components" ):
348
+ for component in _context .data .components :
349
+ if component .get ("components" ):
350
+ __args .append (
351
+ [_value ["value" ] for _value in component ["components" ]][0 ]
352
+ )
353
+ else :
354
+ __args .append ([_value .value for _value in component .components ][0 ])
355
+
356
+ self ._dispatch .dispatch ("on_modal" , _context )
357
+
358
+ self ._dispatch .dispatch (_name , * __args , ** __kwargs )
359
+ self ._dispatch .dispatch ("on_interaction" , _context )
360
+ self ._dispatch .dispatch ("on_interaction_create" , _context )
361
+ elif event != "TYPING_START" :
362
+ name : str = event .lower ()
363
+ try :
364
+ _event_path : list = [section .capitalize () for section in name .split ("_" )]
365
+ _name : str = _event_path [0 ] if len (_event_path ) < 3 else "" .join (_event_path [:- 1 ])
366
+ __obj : object = getattr (__import__ (path ), _name )
367
+
368
+ # name in {"_create", "_add"} returns False (tested w message_create)
369
+ if any (_ in name for _ in {"_create" , "_update" , "_add" , "_remove" , "_delete" }):
370
+ data ["_client" ] = self ._http
371
+
372
+ self ._dispatch .dispatch (f"on_{ name } " , __obj (** data )) # noqa
373
+ except AttributeError as error :
374
+ log .fatal (f"An error occured dispatching { name } : { error } " )
385
375
self ._dispatch .dispatch ("raw_socket_create" , data )
386
376
387
377
def __contextualize (self , data : dict ) -> object :
@@ -621,3 +611,20 @@ def shard(self) -> Optional[List[Tuple[int]]]:
621
611
def presence (self ) -> Optional [ClientPresence ]:
622
612
"""Returns the current presence."""
623
613
return self .__presence
614
+
615
+ async def _update_presence (self , presence : ClientPresence ) -> None :
616
+ """
617
+ Sends an ``UPDATE_PRESENCE`` packet to the gateway.
618
+
619
+ .. note::
620
+ There is a ratelimit to using this method (5 per minute).
621
+ As there's no gateway ratelimiter yet, breaking this ratelimit
622
+ will force your bot to disconnect.
623
+
624
+ :param presence: The presence to change the bot to on identify.
625
+ :type presence: ClientPresence
626
+ """
627
+ payload : dict = {"op" : OpCodeType .PRESENCE , "d" : presence ._json }
628
+ await self ._send_packet (payload )
629
+ log .debug (f"UPDATE_PRESENCE: { presence ._json } " )
630
+ self .__presence = presence
0 commit comments