dshellInterpreter 0.1.13__py3-none-any.whl → 0.1.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dshellInterpreter might be problematic. Click here for more details.
- Dshell/DISCORD_COMMANDS/dshell_channel.py +55 -2
- Dshell/DISCORD_COMMANDS/dshell_member.py +41 -3
- Dshell/DISCORD_COMMANDS/dshell_message.py +32 -3
- Dshell/_DshellInterpreteur/dshell_interpreter.py +7 -3
- Dshell/_DshellParser/ast_nodes.py +160 -0
- Dshell/_DshellParser/dshell_parser.py +20 -1
- Dshell/_DshellTokenizer/dshell_keywords.py +13 -1
- Dshell/_DshellTokenizer/dshell_token_type.py +14 -0
- {dshellinterpreter-0.1.13.dist-info → dshellinterpreter-0.1.14.dist-info}/METADATA +1 -1
- dshellinterpreter-0.1.14.dist-info/RECORD +19 -0
- dshellinterpreter-0.1.13.dist-info/RECORD +0 -19
- {dshellinterpreter-0.1.13.dist-info → dshellinterpreter-0.1.14.dist-info}/WHEEL +0 -0
- {dshellinterpreter-0.1.13.dist-info → dshellinterpreter-0.1.14.dist-info}/licenses/LICENSE +0 -0
- {dshellinterpreter-0.1.13.dist-info → dshellinterpreter-0.1.14.dist-info}/top_level.txt +0 -0
|
@@ -8,7 +8,9 @@ __all__ = [
|
|
|
8
8
|
'dshell_create_text_channel',
|
|
9
9
|
'dshell_delete_channel',
|
|
10
10
|
'dshell_delete_channels',
|
|
11
|
-
'dshell_create_voice_channel'
|
|
11
|
+
'dshell_create_voice_channel',
|
|
12
|
+
'dshell_edit_text_channel',
|
|
13
|
+
'dshell_edit_voice_channel'
|
|
12
14
|
]
|
|
13
15
|
|
|
14
16
|
|
|
@@ -69,7 +71,7 @@ async def dshell_delete_channel(ctx: Message, channel=None, reason=None, timeout
|
|
|
69
71
|
channel_to_delete = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
70
72
|
|
|
71
73
|
if channel_to_delete is None:
|
|
72
|
-
raise Exception(f"
|
|
74
|
+
raise Exception(f"Channel {channel} not found !")
|
|
73
75
|
|
|
74
76
|
await sleep(timeout)
|
|
75
77
|
|
|
@@ -90,3 +92,54 @@ async def dshell_delete_channels(ctx: Message, name=None, regex=None, reason=Non
|
|
|
90
92
|
|
|
91
93
|
elif regex is not None and search(regex, channel.name):
|
|
92
94
|
await channel.delete(reason=reason)
|
|
95
|
+
|
|
96
|
+
async def dshell_edit_text_channel(ctx: Message,
|
|
97
|
+
channel=None,
|
|
98
|
+
name=None,
|
|
99
|
+
position=MISSING,
|
|
100
|
+
slowmode=MISSING,
|
|
101
|
+
topic=MISSING, nsfw=MISSING,
|
|
102
|
+
permission: dict[Union[Member, Role], PermissionOverwrite] = MISSING,
|
|
103
|
+
reason=None):
|
|
104
|
+
"""
|
|
105
|
+
Edits a text channel on the server
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
channel_to_edit = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
109
|
+
|
|
110
|
+
if channel_to_edit is None:
|
|
111
|
+
raise Exception(f"Channel {channel} not found !")
|
|
112
|
+
|
|
113
|
+
await channel_to_edit.edit(name=name,
|
|
114
|
+
position=position,
|
|
115
|
+
slowmode_delay=slowmode,
|
|
116
|
+
topic=topic,
|
|
117
|
+
nsfw=nsfw,
|
|
118
|
+
overwrites=permission,
|
|
119
|
+
reason=reason)
|
|
120
|
+
|
|
121
|
+
return channel_to_edit.id
|
|
122
|
+
|
|
123
|
+
async def dshell_edit_voice_channel(ctx: Message,
|
|
124
|
+
channel=None,
|
|
125
|
+
name=None,
|
|
126
|
+
position=MISSING,
|
|
127
|
+
bitrate=MISSING,
|
|
128
|
+
permission: dict[Union[Member, Role], PermissionOverwrite] = MISSING,
|
|
129
|
+
reason=None):
|
|
130
|
+
"""
|
|
131
|
+
Edits a voice channel on the server
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
channel_to_edit = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
135
|
+
|
|
136
|
+
if channel_to_edit is None:
|
|
137
|
+
raise Exception(f"Channel {channel} not found !")
|
|
138
|
+
|
|
139
|
+
await channel_to_edit.edit(name=name,
|
|
140
|
+
position=position,
|
|
141
|
+
bitrate=bitrate,
|
|
142
|
+
overwrites=permission,
|
|
143
|
+
reason=reason)
|
|
144
|
+
|
|
145
|
+
return channel_to_edit.id
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
from discord import MISSING, Message
|
|
1
|
+
from discord import MISSING, Message, Member
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
__all__ = [
|
|
5
5
|
"dshell_ban_member",
|
|
6
6
|
"dshell_unban_member",
|
|
7
7
|
"dshell_kick_member",
|
|
8
|
-
"dshell_rename_member"
|
|
8
|
+
"dshell_rename_member",
|
|
9
|
+
"dshell_add_roles",
|
|
10
|
+
"dshell_remove_roles",
|
|
9
11
|
]
|
|
10
12
|
|
|
11
13
|
async def dshell_ban_member(ctx: Message, member: int, reason: str = MISSING):
|
|
@@ -64,4 +66,40 @@ async def dshell_rename_member(ctx: Message, new_name, member=None):
|
|
|
64
66
|
|
|
65
67
|
await renamed_member.edit(nick=new_name)
|
|
66
68
|
|
|
67
|
-
return renamed_member.id
|
|
69
|
+
return renamed_member.id
|
|
70
|
+
|
|
71
|
+
async def dshell_add_roles(ctx: Message, roles: list[int], member=None, reason: str = None):
|
|
72
|
+
"""
|
|
73
|
+
Adds roles to a member in the server.
|
|
74
|
+
"""
|
|
75
|
+
target_member: Member = ctx.author if member is None else ctx.channel.guild.get_member(member)
|
|
76
|
+
|
|
77
|
+
if not target_member:
|
|
78
|
+
return 1 # Member not found in the server
|
|
79
|
+
|
|
80
|
+
roles_to_add = [ctx.channel.guild.get_role(role_id) for role_id in roles if ctx.channel.guild.get_role(role_id)]
|
|
81
|
+
|
|
82
|
+
if not roles_to_add:
|
|
83
|
+
return 2 # No valid roles found
|
|
84
|
+
|
|
85
|
+
await target_member.add_roles(*roles_to_add, reason=reason)
|
|
86
|
+
|
|
87
|
+
return target_member.id
|
|
88
|
+
|
|
89
|
+
async def dshell_remove_roles(ctx: Message, roles: list[int], member=None, reason: str = None):
|
|
90
|
+
"""
|
|
91
|
+
Removes roles from a member in the server.
|
|
92
|
+
"""
|
|
93
|
+
target_member: Member = ctx.author if member is None else ctx.channel.guild.get_member(member)
|
|
94
|
+
|
|
95
|
+
if not target_member:
|
|
96
|
+
return 1 # Member not found in the server
|
|
97
|
+
|
|
98
|
+
roles_to_remove = [ctx.channel.guild.get_role(role_id) for role_id in roles if ctx.channel.guild.get_role(role_id)]
|
|
99
|
+
|
|
100
|
+
if not roles_to_remove:
|
|
101
|
+
return 2 # No valid roles found
|
|
102
|
+
|
|
103
|
+
await target_member.remove_roles(*roles_to_remove, reason=reason)
|
|
104
|
+
|
|
105
|
+
return target_member.id
|
|
@@ -9,7 +9,9 @@ __all__ = [
|
|
|
9
9
|
'dshell_purge_message',
|
|
10
10
|
'dshell_edit_message',
|
|
11
11
|
'dshell_research_regex_message',
|
|
12
|
-
'dshell_research_regex_in_content'
|
|
12
|
+
'dshell_research_regex_in_content',
|
|
13
|
+
'dshell_add_reactions',
|
|
14
|
+
'dshell_remove_reactions'
|
|
13
15
|
]
|
|
14
16
|
|
|
15
17
|
|
|
@@ -110,7 +112,34 @@ async def dshell_research_regex_in_content(ctx: Message, regex, content):
|
|
|
110
112
|
"""
|
|
111
113
|
|
|
112
114
|
if not search(regex, content):
|
|
113
|
-
return
|
|
115
|
+
return False
|
|
114
116
|
|
|
115
|
-
return
|
|
117
|
+
return True
|
|
116
118
|
|
|
119
|
+
async def dshell_add_reactions(ctx: Message, reactions, message_id=None):
|
|
120
|
+
"""
|
|
121
|
+
Adds reactions to a message
|
|
122
|
+
"""
|
|
123
|
+
message = ctx.channel if message_id is None else ctx.channel.get_partial_message(message_id) # builds a reference to the message (even if it doesn't exist)
|
|
124
|
+
|
|
125
|
+
if isinstance(reactions, str):
|
|
126
|
+
reactions = [reactions]
|
|
127
|
+
|
|
128
|
+
for reaction in reactions:
|
|
129
|
+
await message.add_reaction(reaction)
|
|
130
|
+
|
|
131
|
+
return message.id
|
|
132
|
+
|
|
133
|
+
async def dshell_remove_reactions(ctx: Message, reactions, message_id=None):
|
|
134
|
+
"""
|
|
135
|
+
Removes reactions from a message
|
|
136
|
+
"""
|
|
137
|
+
message = ctx.channel if message_id is None else ctx.channel.get_partial_message(message_id) # builds a reference to the message (even if it doesn't exist)
|
|
138
|
+
|
|
139
|
+
if isinstance(reactions, str):
|
|
140
|
+
reactions = [reactions]
|
|
141
|
+
|
|
142
|
+
for reaction in reactions:
|
|
143
|
+
await message.clear_reaction(reaction)
|
|
144
|
+
|
|
145
|
+
return message.id
|
|
@@ -24,16 +24,20 @@ class DshellInterpreteur:
|
|
|
24
24
|
Make what you want with Dshell code to interact with Discord !
|
|
25
25
|
"""
|
|
26
26
|
|
|
27
|
-
def __init__(self, code: str, ctx: context, debug: bool = False):
|
|
27
|
+
def __init__(self, code: str, ctx: context, debug: bool = False, vars: Optional[dict[str, Any]] = None):
|
|
28
28
|
"""
|
|
29
29
|
Interpreter Dshell code
|
|
30
30
|
:param code: The code to interpret. Each line must end with a newline character, except SEPARATOR and SUB_SEPARATOR tokens.
|
|
31
|
+
:param ctx: The context in which the code is executed. It can be a Discord bot, a message, or a channel.
|
|
32
|
+
:param debug: If True, prints the AST of the code.
|
|
33
|
+
:param vars: Optional dictionary of variables to initialize in the interpreter's environment.
|
|
31
34
|
"""
|
|
32
35
|
self.ast: list[ASTNode] = parse(DshellTokenizer(code).start(), StartNode([]))[0]
|
|
33
|
-
self.env: dict[str, Any] = {}
|
|
36
|
+
self.env: dict[str, Any] = vars or {}
|
|
34
37
|
self.ctx: context = ctx
|
|
35
38
|
if debug:
|
|
36
39
|
print_ast(self.ast)
|
|
40
|
+
self.env['__ret__'] = None
|
|
37
41
|
|
|
38
42
|
async def execute(self, ast: Optional[list[All_nodes]] = None):
|
|
39
43
|
"""
|
|
@@ -57,7 +61,7 @@ class DshellInterpreteur:
|
|
|
57
61
|
await self.execute(node.body)
|
|
58
62
|
|
|
59
63
|
if isinstance(node, CommandNode):
|
|
60
|
-
self.env['
|
|
64
|
+
self.env['__ret__'] = await call_function(dshell_commands[node.name], node.body, self)
|
|
61
65
|
|
|
62
66
|
elif isinstance(node, IfNode):
|
|
63
67
|
elif_valid = False
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from typing import Optional, Any
|
|
2
|
+
from random import randint
|
|
2
3
|
|
|
3
4
|
from .._DshellTokenizer.dshell_token_type import Token
|
|
4
5
|
|
|
@@ -39,6 +40,16 @@ class StartNode(ASTNode):
|
|
|
39
40
|
def __repr__(self):
|
|
40
41
|
return f"<Command> - {self.body}"
|
|
41
42
|
|
|
43
|
+
def to_dict(self):
|
|
44
|
+
"""
|
|
45
|
+
Convert the StartNode to a dictionary representation.
|
|
46
|
+
:return: Dictionary representation of the StartNode.
|
|
47
|
+
"""
|
|
48
|
+
return {
|
|
49
|
+
"type": "StartNode",
|
|
50
|
+
"body": [token.to_dict() for token in self.body]
|
|
51
|
+
}
|
|
52
|
+
|
|
42
53
|
|
|
43
54
|
class ElseNode(ASTNode):
|
|
44
55
|
"""
|
|
@@ -53,6 +64,16 @@ class ElseNode(ASTNode):
|
|
|
53
64
|
def __repr__(self):
|
|
54
65
|
return f"<Else> - {self.body}"
|
|
55
66
|
|
|
67
|
+
def to_dict(self):
|
|
68
|
+
"""
|
|
69
|
+
Convert the ElseNode to a dictionary representation.
|
|
70
|
+
:return: Dictionary representation of the ElseNode.
|
|
71
|
+
"""
|
|
72
|
+
return {
|
|
73
|
+
"type": "ElseNode",
|
|
74
|
+
"body": [token.to_dict() for token in self.body]
|
|
75
|
+
}
|
|
76
|
+
|
|
56
77
|
|
|
57
78
|
class ElifNode(ASTNode):
|
|
58
79
|
"""
|
|
@@ -71,6 +92,18 @@ class ElifNode(ASTNode):
|
|
|
71
92
|
def __repr__(self):
|
|
72
93
|
return f"<Elif> - {self.condition} - {self.body}"
|
|
73
94
|
|
|
95
|
+
def to_dict(self):
|
|
96
|
+
"""
|
|
97
|
+
Convert the ElifNode to a dictionary representation.
|
|
98
|
+
:return: Dictionary representation of the ElifNode.
|
|
99
|
+
"""
|
|
100
|
+
return {
|
|
101
|
+
"type": "ElifNode",
|
|
102
|
+
"condition": [token.to_dict() for token in self.condition],
|
|
103
|
+
"body": [token.to_dict() for token in self.body],
|
|
104
|
+
"parent": self.parent.id # Assuming parent is an IfNode, we store its ID
|
|
105
|
+
}
|
|
106
|
+
|
|
74
107
|
|
|
75
108
|
class IfNode(ASTNode):
|
|
76
109
|
"""
|
|
@@ -88,10 +121,24 @@ class IfNode(ASTNode):
|
|
|
88
121
|
self.body = body
|
|
89
122
|
self.elif_nodes = elif_nodes
|
|
90
123
|
self.else_body = else_body
|
|
124
|
+
self.id = randint(0, 1000000) # Unique identifier for the IfNode instance
|
|
91
125
|
|
|
92
126
|
def __repr__(self):
|
|
93
127
|
return f"<If> - {self.condition} - {self.body} *- {self.elif_nodes} **- {self.else_body}"
|
|
94
128
|
|
|
129
|
+
def to_dict(self):
|
|
130
|
+
"""
|
|
131
|
+
Convert the IfNode to a dictionary representation.
|
|
132
|
+
:return: Dictionary representation of the IfNode.
|
|
133
|
+
"""
|
|
134
|
+
return {
|
|
135
|
+
"type": "IfNode",
|
|
136
|
+
"condition": [token.to_dict() for token in self.condition],
|
|
137
|
+
"body": [token.to_dict() for token in self.body],
|
|
138
|
+
"elif_nodes": [elif_node.to_dict() for elif_node in self.elif_nodes] if self.elif_nodes else None,
|
|
139
|
+
"else_body": self.else_body.to_dict() if self.else_body else None,
|
|
140
|
+
"id": self.id
|
|
141
|
+
}
|
|
95
142
|
|
|
96
143
|
class LoopNode(ASTNode):
|
|
97
144
|
"""
|
|
@@ -108,6 +155,16 @@ class LoopNode(ASTNode):
|
|
|
108
155
|
def __repr__(self):
|
|
109
156
|
return f"<Loop> - {self.variable.name} -> {self.variable.body} *- {self.body}"
|
|
110
157
|
|
|
158
|
+
def to_dict(self):
|
|
159
|
+
"""
|
|
160
|
+
Convert the LoopNode to a dictionary representation.
|
|
161
|
+
:return: Dictionary representation of the LoopNode.
|
|
162
|
+
"""
|
|
163
|
+
return {
|
|
164
|
+
"type": "LoopNode",
|
|
165
|
+
"variable": self.variable.to_dict(),
|
|
166
|
+
"body": [token.to_dict() for token in self.body]
|
|
167
|
+
}
|
|
111
168
|
|
|
112
169
|
class ArgsCommandNode(ASTNode):
|
|
113
170
|
"""
|
|
@@ -122,6 +179,16 @@ class ArgsCommandNode(ASTNode):
|
|
|
122
179
|
def __repr__(self):
|
|
123
180
|
return f"<Args Command> - {self.body}"
|
|
124
181
|
|
|
182
|
+
def to_dict(self):
|
|
183
|
+
"""
|
|
184
|
+
Convert the ArgsCommandNode to a dictionary representation.
|
|
185
|
+
:return: Dictionary representation of the ArgsCommandNode.
|
|
186
|
+
"""
|
|
187
|
+
return {
|
|
188
|
+
"type": "ArgsCommandNode",
|
|
189
|
+
"body": [token.to_dict() for token in self.body]
|
|
190
|
+
}
|
|
191
|
+
|
|
125
192
|
|
|
126
193
|
class CommandNode(ASTNode):
|
|
127
194
|
"""
|
|
@@ -138,6 +205,17 @@ class CommandNode(ASTNode):
|
|
|
138
205
|
def __repr__(self):
|
|
139
206
|
return f"<{self.name}> - {self.body}"
|
|
140
207
|
|
|
208
|
+
def to_dict(self):
|
|
209
|
+
"""
|
|
210
|
+
Convert the CommandNode to a dictionary representation.
|
|
211
|
+
:return: Dictionary representation of the CommandNode.
|
|
212
|
+
"""
|
|
213
|
+
return {
|
|
214
|
+
"type": "CommandNode",
|
|
215
|
+
"name": self.name,
|
|
216
|
+
"body": self.body.to_dict()
|
|
217
|
+
}
|
|
218
|
+
|
|
141
219
|
|
|
142
220
|
class VarNode(ASTNode):
|
|
143
221
|
"""
|
|
@@ -154,6 +232,17 @@ class VarNode(ASTNode):
|
|
|
154
232
|
def __repr__(self):
|
|
155
233
|
return f"<VAR> - {self.name} *- {self.body}"
|
|
156
234
|
|
|
235
|
+
def to_dict(self):
|
|
236
|
+
"""
|
|
237
|
+
Convert the VarNode to a dictionary representation.
|
|
238
|
+
:return: Dictionary representation of the VarNode.
|
|
239
|
+
"""
|
|
240
|
+
return {
|
|
241
|
+
"type": "VarNode",
|
|
242
|
+
"name": self.name.to_dict(),
|
|
243
|
+
"body": [token.to_dict() for token in self.body]
|
|
244
|
+
}
|
|
245
|
+
|
|
157
246
|
|
|
158
247
|
class EndNode(ASTNode):
|
|
159
248
|
"""
|
|
@@ -165,6 +254,15 @@ class EndNode(ASTNode):
|
|
|
165
254
|
def __repr__(self):
|
|
166
255
|
return f"<END>"
|
|
167
256
|
|
|
257
|
+
def to_dict(self):
|
|
258
|
+
"""
|
|
259
|
+
Convert the EndNode to a dictionary representation.
|
|
260
|
+
:return: Dictionary representation of the EndNode.
|
|
261
|
+
"""
|
|
262
|
+
return {
|
|
263
|
+
"type": "EndNode"
|
|
264
|
+
}
|
|
265
|
+
|
|
168
266
|
|
|
169
267
|
class FieldEmbedNode(ASTNode):
|
|
170
268
|
"""
|
|
@@ -179,6 +277,16 @@ class FieldEmbedNode(ASTNode):
|
|
|
179
277
|
def __repr__(self):
|
|
180
278
|
return f"<EMBED_FIELD> - {self.body}"
|
|
181
279
|
|
|
280
|
+
def to_dict(self):
|
|
281
|
+
"""
|
|
282
|
+
Convert the FieldEmbedNode to a dictionary representation.
|
|
283
|
+
:return: Dictionary representation of the FieldEmbedNode.
|
|
284
|
+
"""
|
|
285
|
+
return {
|
|
286
|
+
"type": "FieldEmbedNode",
|
|
287
|
+
"body": [token.to_dict() for token in self.body]
|
|
288
|
+
}
|
|
289
|
+
|
|
182
290
|
|
|
183
291
|
class EmbedNode(ASTNode):
|
|
184
292
|
"""
|
|
@@ -195,6 +303,17 @@ class EmbedNode(ASTNode):
|
|
|
195
303
|
def __repr__(self):
|
|
196
304
|
return f"<EMBED> - {self.body}"
|
|
197
305
|
|
|
306
|
+
def to_dict(self):
|
|
307
|
+
"""
|
|
308
|
+
Convert the EmbedNode to a dictionary representation.
|
|
309
|
+
:return: Dictionary representation of the EmbedNode.
|
|
310
|
+
"""
|
|
311
|
+
return {
|
|
312
|
+
"type": "EmbedNode",
|
|
313
|
+
"body": [token.to_dict() for token in self.body],
|
|
314
|
+
"fields": [field.to_dict() for field in self.fields]
|
|
315
|
+
}
|
|
316
|
+
|
|
198
317
|
|
|
199
318
|
class PermissionNode(ASTNode):
|
|
200
319
|
"""
|
|
@@ -209,6 +328,16 @@ class PermissionNode(ASTNode):
|
|
|
209
328
|
def __repr__(self):
|
|
210
329
|
return f"<PERMISSION> - {self.body}"
|
|
211
330
|
|
|
331
|
+
def to_dict(self):
|
|
332
|
+
"""
|
|
333
|
+
Convert the PermissionNode to a dictionary representation.
|
|
334
|
+
:return: Dictionary representation of the PermissionNode.
|
|
335
|
+
"""
|
|
336
|
+
return {
|
|
337
|
+
"type": "PermissionNode",
|
|
338
|
+
"body": [token.to_dict() for token in self.body]
|
|
339
|
+
}
|
|
340
|
+
|
|
212
341
|
|
|
213
342
|
class SleepNode(ASTNode):
|
|
214
343
|
"""
|
|
@@ -223,6 +352,16 @@ class SleepNode(ASTNode):
|
|
|
223
352
|
def __repr__(self):
|
|
224
353
|
return f"<SLEEP> - {self.body}"
|
|
225
354
|
|
|
355
|
+
def to_dict(self):
|
|
356
|
+
"""
|
|
357
|
+
Convert the SleepNode to a dictionary representation.
|
|
358
|
+
:return: Dictionary representation of the SleepNode.
|
|
359
|
+
"""
|
|
360
|
+
return {
|
|
361
|
+
"type": "SleepNode",
|
|
362
|
+
"body": [token.to_dict() for token in self.body]
|
|
363
|
+
}
|
|
364
|
+
|
|
226
365
|
|
|
227
366
|
class IdentOperationNode(ASTNode):
|
|
228
367
|
"""
|
|
@@ -244,6 +383,17 @@ class IdentOperationNode(ASTNode):
|
|
|
244
383
|
def __repr__(self):
|
|
245
384
|
return f"<IDENT OPERATION> - {self.ident}.{self.function}({self.args})"
|
|
246
385
|
|
|
386
|
+
def to_dict(self):
|
|
387
|
+
"""
|
|
388
|
+
Convert the IdentOperationNode to a dictionary representation.
|
|
389
|
+
:return: Dictionary representation of the IdentOperationNode.
|
|
390
|
+
"""
|
|
391
|
+
return {
|
|
392
|
+
"type": "IdentOperationNode",
|
|
393
|
+
"ident": self.ident.to_dict(),
|
|
394
|
+
"function": self.function.to_dict(),
|
|
395
|
+
"args": self.args.to_dict()
|
|
396
|
+
}
|
|
247
397
|
|
|
248
398
|
class ListNode(ASTNode):
|
|
249
399
|
"""
|
|
@@ -260,6 +410,16 @@ class ListNode(ASTNode):
|
|
|
260
410
|
self.len_iterable: int = len(body)
|
|
261
411
|
self.iterateur_count: int = 0
|
|
262
412
|
|
|
413
|
+
def to_dict(self):
|
|
414
|
+
"""
|
|
415
|
+
Convert the ListNode to a dictionary representation.
|
|
416
|
+
:return: Dictionary representation of the ListNode.
|
|
417
|
+
"""
|
|
418
|
+
return {
|
|
419
|
+
"type": "ListNode",
|
|
420
|
+
"body": [token.to_dict() for token in self.iterable]
|
|
421
|
+
}
|
|
422
|
+
|
|
263
423
|
def add(self, value: Any):
|
|
264
424
|
"""
|
|
265
425
|
Add a value to the list.
|
|
@@ -3,7 +3,8 @@ __all__ = [
|
|
|
3
3
|
"parser_inline",
|
|
4
4
|
"to_postfix",
|
|
5
5
|
"parse_postfix_expression",
|
|
6
|
-
"print_ast"
|
|
6
|
+
"print_ast",
|
|
7
|
+
"ast_to_dict",
|
|
7
8
|
]
|
|
8
9
|
|
|
9
10
|
from typing import Union, TYPE_CHECKING
|
|
@@ -200,6 +201,24 @@ elif first_token_line.type == DTT.LIST: # si le token est une liste (qui comport
|
|
|
200
201
|
last_block.body.append(list_node)
|
|
201
202
|
"""
|
|
202
203
|
|
|
204
|
+
def ast_to_dict(obj):
|
|
205
|
+
if isinstance(obj, list):
|
|
206
|
+
return [ast_to_dict(item) for item in obj]
|
|
207
|
+
elif hasattr(obj, "to_dict"):
|
|
208
|
+
return obj.to_dict()
|
|
209
|
+
else:
|
|
210
|
+
return obj # fallback for primitives or tokens
|
|
211
|
+
|
|
212
|
+
def dict_to_ast(data):
|
|
213
|
+
"""
|
|
214
|
+
Convertit un dictionnaire en une structure AST.
|
|
215
|
+
:param data: le dictionnaire à convertir
|
|
216
|
+
:return: la structure AST correspondante
|
|
217
|
+
"""
|
|
218
|
+
if isinstance(data, list):
|
|
219
|
+
return [dict_to_ast(item) for item in data]
|
|
220
|
+
elif isinstance(data, dict):
|
|
221
|
+
pass
|
|
203
222
|
|
|
204
223
|
def parser_inline(tokens: list[Token]) -> tuple[list[list[Token]], bool]:
|
|
205
224
|
"""
|
|
@@ -21,19 +21,31 @@ dshell_discord_keyword: set[str] = {
|
|
|
21
21
|
'embed', '#embed', 'field', 'perm', 'permission', '#perm', '#permission'
|
|
22
22
|
}
|
|
23
23
|
dshell_commands: dict[str, Callable] = {
|
|
24
|
+
|
|
24
25
|
"sm": dshell_send_message, # send message
|
|
25
26
|
"dm": dshell_delete_message,
|
|
26
27
|
"pm": dshell_purge_message,
|
|
28
|
+
"em": dshell_edit_message, # edit message
|
|
29
|
+
|
|
27
30
|
"cc": dshell_create_text_channel, # create channel
|
|
28
31
|
"cvc": dshell_create_voice_channel, # create voice channel
|
|
29
32
|
"dc": dshell_delete_channel, # delete channel
|
|
30
33
|
"dcs": dshell_delete_channels, # delete several channels by name or regex
|
|
34
|
+
|
|
31
35
|
"bm": dshell_ban_member, # ban member
|
|
32
36
|
"um": dshell_unban_member, # unban member
|
|
33
37
|
"km": dshell_kick_member, # kick member
|
|
34
|
-
"
|
|
38
|
+
"rm": dshell_rename_member, # rename member
|
|
39
|
+
|
|
35
40
|
"srm": dshell_research_regex_message, # research regex in message
|
|
36
41
|
"src": dshell_research_regex_in_content, # research regex in content
|
|
42
|
+
|
|
43
|
+
"ec": dshell_edit_text_channel, # edit text channel
|
|
44
|
+
"evc": dshell_edit_voice_channel, # edit voice channel
|
|
45
|
+
|
|
46
|
+
"arr": dshell_add_reactions, # add reactions to a message
|
|
47
|
+
"rrr": dshell_remove_reactions, # remove reactions from a message
|
|
48
|
+
|
|
37
49
|
}
|
|
38
50
|
|
|
39
51
|
dshell_mathematical_operators: dict[str, tuple[Callable, int]] = {
|
|
@@ -39,3 +39,17 @@ class Token:
|
|
|
39
39
|
|
|
40
40
|
def __repr__(self):
|
|
41
41
|
return f"<{self.type.name} '{self.value}'>"
|
|
42
|
+
|
|
43
|
+
def to_dict(self):
|
|
44
|
+
def serialize_value(value):
|
|
45
|
+
if isinstance(value, list):
|
|
46
|
+
return [serialize_value(v) for v in value]
|
|
47
|
+
elif isinstance(value, Token):
|
|
48
|
+
return value.to_dict()
|
|
49
|
+
return value
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
"type": self.type.name,
|
|
53
|
+
"value": serialize_value(self.value),
|
|
54
|
+
"position": self.position
|
|
55
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Dshell/__init__.py,sha256=UPvXnewe_8FX9aoevMA78UN1k8AY-u8LTY3vEVxaDxw,72
|
|
2
|
+
Dshell/DISCORD_COMMANDS/__init__.py,sha256=unbZE4sxFCbUQ4Qptr1BhWu-nwhvI2oRzcDLtRmX6Ug,92
|
|
3
|
+
Dshell/DISCORD_COMMANDS/dshell_channel.py,sha256=3tOVZhfFSie_Kjv8HhgsPfzWQuppLbZ4elmf04KfvrM,5865
|
|
4
|
+
Dshell/DISCORD_COMMANDS/dshell_member.py,sha256=4cmpcu9RGHVUOGcF9pSnnxh7kEJQWAel4BBQ6Vicvbs,3126
|
|
5
|
+
Dshell/DISCORD_COMMANDS/dshell_message.py,sha256=T4MeAD_AnE5HFUlE9qMWbQtznR9-nJgGZ72rcA1K2_8,4415
|
|
6
|
+
Dshell/_DshellInterpreteur/__init__.py,sha256=xy5-J-R3YmY99JF3NBHTRRLsComFxpjnCA5xacISctU,35
|
|
7
|
+
Dshell/_DshellInterpreteur/dshell_interpreter.py,sha256=LFysDRsM-4w14l6EzIkJJYLS3ZNjeU_e4tMx2TURnjM,17650
|
|
8
|
+
Dshell/_DshellParser/__init__.py,sha256=ONDfhZMvClqP_6tE8SLjp-cf3pXL-auQYnfYRrHZxC4,56
|
|
9
|
+
Dshell/_DshellParser/ast_nodes.py,sha256=o21a9Rdgq00koQSX8uj1uKMVdEHsgJK55bgaqK8bZAM,14447
|
|
10
|
+
Dshell/_DshellParser/dshell_parser.py,sha256=87VWNHOeLfNTieie4oKPYw9ieqtqFOVU6tEV9h1VVzI,14657
|
|
11
|
+
Dshell/_DshellTokenizer/__init__.py,sha256=LIQSRhDx2B9pmPx5ADMwwD0Xr9ybneVLhHH8qrJWw_s,172
|
|
12
|
+
Dshell/_DshellTokenizer/dshell_keywords.py,sha256=1aq5z23AFJ1V4th_3qOJrAiEKcMH7gpZJn6n4ln9OQA,4234
|
|
13
|
+
Dshell/_DshellTokenizer/dshell_token_type.py,sha256=Q8Jpil9S3-Tin1sXEHW7cnNdDdUh7Fiv8_lki0OWC0E,1443
|
|
14
|
+
Dshell/_DshellTokenizer/dshell_tokenizer.py,sha256=DSGiSHj9jLqP7RkC-8WFRqFvitJ7P4b7p0CJn4ek7hE,5831
|
|
15
|
+
dshellinterpreter-0.1.14.dist-info/licenses/LICENSE,sha256=lNgcw1_xb7QENAQi3uHGymaFtbs0RV-ihiCd7AoLQjA,1082
|
|
16
|
+
dshellinterpreter-0.1.14.dist-info/METADATA,sha256=aRkW5zI8wXn4AYyEGc83BpDd4M5QRG2eeqYrr_BDwS4,1096
|
|
17
|
+
dshellinterpreter-0.1.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
18
|
+
dshellinterpreter-0.1.14.dist-info/top_level.txt,sha256=B4CMhtmchGwPQJLuqUy0GhRG-0cUGxKL4GqEbCiB_vE,7
|
|
19
|
+
dshellinterpreter-0.1.14.dist-info/RECORD,,
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
Dshell/__init__.py,sha256=UPvXnewe_8FX9aoevMA78UN1k8AY-u8LTY3vEVxaDxw,72
|
|
2
|
-
Dshell/DISCORD_COMMANDS/__init__.py,sha256=unbZE4sxFCbUQ4Qptr1BhWu-nwhvI2oRzcDLtRmX6Ug,92
|
|
3
|
-
Dshell/DISCORD_COMMANDS/dshell_channel.py,sha256=pKN-jzPSk2UI0LgUt31LsOYs5bWLys6LcQclQ-AwbXE,3713
|
|
4
|
-
Dshell/DISCORD_COMMANDS/dshell_member.py,sha256=hV_8tFUa_RLwh-UaoLcHQr4yp0ln2vjvzFW5IJwDGVM,1792
|
|
5
|
-
Dshell/DISCORD_COMMANDS/dshell_message.py,sha256=obfkzhGu561vUP25uMV3fH5OBDE-0bqNOxjyrGGIz60,3416
|
|
6
|
-
Dshell/_DshellInterpreteur/__init__.py,sha256=xy5-J-R3YmY99JF3NBHTRRLsComFxpjnCA5xacISctU,35
|
|
7
|
-
Dshell/_DshellInterpreteur/dshell_interpreter.py,sha256=x1_t-9twq2IaB5aQUJN9XFvXbujMCN1KRX_1uYr9IGA,17289
|
|
8
|
-
Dshell/_DshellParser/__init__.py,sha256=ONDfhZMvClqP_6tE8SLjp-cf3pXL-auQYnfYRrHZxC4,56
|
|
9
|
-
Dshell/_DshellParser/ast_nodes.py,sha256=ZPZAA6yqR62mLAMGVO94wTUVmpYM91qAwSKFiWNAt74,9125
|
|
10
|
-
Dshell/_DshellParser/dshell_parser.py,sha256=SqZRG7i8_vdIFhaQwLi-Q8LWIwyw5FaPFEGMX5vsWwU,14074
|
|
11
|
-
Dshell/_DshellTokenizer/__init__.py,sha256=LIQSRhDx2B9pmPx5ADMwwD0Xr9ybneVLhHH8qrJWw_s,172
|
|
12
|
-
Dshell/_DshellTokenizer/dshell_keywords.py,sha256=Mf48FtTWZN-bgNwFVijFbcQK1bZEEdyutQvu_DXJEVo,3915
|
|
13
|
-
Dshell/_DshellTokenizer/dshell_token_type.py,sha256=p0cR4sxhmq03AqBjd0h_sg2eDzgBmd3dhrrchYkL1Pk,1011
|
|
14
|
-
Dshell/_DshellTokenizer/dshell_tokenizer.py,sha256=DSGiSHj9jLqP7RkC-8WFRqFvitJ7P4b7p0CJn4ek7hE,5831
|
|
15
|
-
dshellinterpreter-0.1.13.dist-info/licenses/LICENSE,sha256=lNgcw1_xb7QENAQi3uHGymaFtbs0RV-ihiCd7AoLQjA,1082
|
|
16
|
-
dshellinterpreter-0.1.13.dist-info/METADATA,sha256=0TodY8g2O0TnvnQvk8HyNtewYPCervGT39yx70-3sJ4,1096
|
|
17
|
-
dshellinterpreter-0.1.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
18
|
-
dshellinterpreter-0.1.13.dist-info/top_level.txt,sha256=B4CMhtmchGwPQJLuqUy0GhRG-0cUGxKL4GqEbCiB_vE,7
|
|
19
|
-
dshellinterpreter-0.1.13.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|