1
+ import inspect
2
+
3
+ from discord import (
4
+ Message ,
5
+ Client ,
6
+ AutoShardedClient
7
+ )
8
+ from typing import (
9
+ Any ,
10
+ Callable ,
11
+ Coroutine
12
+ )
13
+ from .commands import (
14
+ Command ,
15
+ CommandGroup
16
+ )
17
+
18
+ from .context import Context
19
+
20
+ def _create_context (
21
+ message : Message ,
22
+ bot : Client | AutoShardedClient ,
23
+ args : list [Any ],
24
+ prefix : str | Callable | Coroutine ,
25
+ command : Command | CommandGroup ,
26
+ invoked_with : Command | CommandGroup ,
27
+ kwargs : dict [str , Any ] = {},
28
+ invoked_parent : CommandGroup = None ,
29
+ invoked_subcommand : Command = None ,
30
+ cls : Context = None ): # FIXME: typing
31
+ _cls = cls or Context
32
+
33
+ return _cls (
34
+ message = message ,
35
+ bot = bot ,
36
+ args = args ,
37
+ kwargs = kwargs ,
38
+ prefix = prefix ,
39
+ command = command ,
40
+ invoked_with = invoked_with ,
41
+ invoked_parent = invoked_parent ,
42
+ invoked_subcommand = invoked_subcommand
43
+ )
44
+
45
+ def _has_prefix (prefixes : list , message : Message ) -> str :
46
+ for prefix in prefixes :
47
+ if len (message .content .split (prefix ))== 2 :
48
+ return prefix
49
+
50
+ def _find_command (bot : Client | AutoShardedClient , prefix : str , content : str ) -> Command | None :
51
+ name = content .split (prefix , 1 )[1 ].split (" " )
52
+ if len (name )>= 2 :
53
+ if bot .all_commands [name [0 ]] == bot .sub_commands [name [1 ]].parent :
54
+ return bot .sub_commands [name [1 ]]
55
+ elif name [0 ] in bot .all_commands :
56
+ return bot .all_commands [name [0 ]]
57
+ else :
58
+ return bot .all_commands [name [0 ]] if name [0 ] in bot .all_commands else None
59
+
60
+ def _process_arguments (content : str ):
61
+ pass
62
+
63
+ def _find_args (command : Command , message : Message ) -> dict [str , str ]:
64
+ try :
65
+ args = inspect .getfullargspec (command .callback )[0 ]
66
+ except ValueError :
67
+ args = inspect .signature (command .callback )
68
+
69
+ given_args = {}
70
+ if not len (args )> 3 :
71
+ return None
72
+ del args [:3 ]
73
+ iteration = 0
74
+ _temp = " "
75
+ for arg in message .content .split (command .name , 1 )[1 ].strip ().split (" " ):
76
+ if iteration >= len (args ):
77
+ _temp += arg
78
+ else :
79
+ given_args [args [iteration ]] = arg
80
+ iteration += 1
81
+ given_args [args [- 1 ]] += _temp
82
+
83
+ return given_args
84
+
85
+ def process_message (bot : Client | AutoShardedClient , prefixes : str | list , message : Message , context = None ) -> Command :
86
+ """Processes a message, for retrieving a command if the message contains the prefix+command combination.
87
+
88
+ Args:
89
+ bot (Client | AutoShardedClient): Initialized discord.py bot.
90
+ prefixes (str | list): either a string or a list of prefixes.
91
+ message (Message): The message processed for a command.
92
+
93
+ Returns:
94
+ Command: The command found
95
+ Args (dict): All found args
96
+ """
97
+ if (prefix := _has_prefix (prefixes , message )):
98
+ if (command := _find_command (bot , prefix , message .content )):
99
+ args = _find_args (command , message )
100
+ context = _create_context (message , bot , args = args , kwargs = {}, prefix = prefixes , command = command , invoked_with = command , cls = context )
101
+ return command , context
0 commit comments