dshellInterpreter 0.2.1__tar.gz → 0.2.3__tar.gz
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.
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/DISCORD_COMMANDS/__init__.py +1 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/DISCORD_COMMANDS/dshell_channel.py +66 -19
- dshellinterpreter-0.2.3/Dshell/DISCORD_COMMANDS/dshell_member.py +186 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/DISCORD_COMMANDS/dshell_message.py +39 -17
- dshellinterpreter-0.2.3/Dshell/DISCORD_COMMANDS/dshell_pastbin.py +30 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/_DshellInterpreteur/dshell_interpreter.py +25 -8
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/_DshellParser/ast_nodes.py +18 -1
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/_DshellParser/dshell_parser.py +5 -3
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/_DshellTokenizer/dshell_keywords.py +9 -3
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/PKG-INFO +1 -1
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/dshellInterpreter.egg-info/PKG-INFO +1 -1
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/dshellInterpreter.egg-info/SOURCES.txt +1 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/setup.py +1 -1
- dshellinterpreter-0.2.1/Dshell/DISCORD_COMMANDS/dshell_member.py +0 -105
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/_DshellInterpreteur/__init__.py +0 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/_DshellParser/__init__.py +0 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/_DshellTokenizer/__init__.py +0 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/_DshellTokenizer/dshell_token_type.py +0 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/_DshellTokenizer/dshell_tokenizer.py +0 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/__init__.py +0 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/LICENSE +0 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/README.md +0 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/dshellInterpreter.egg-info/dependency_links.txt +0 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/dshellInterpreter.egg-info/requires.txt +0 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/dshellInterpreter.egg-info/top_level.txt +0 -0
- {dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/setup.cfg +0 -0
{dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/DISCORD_COMMANDS/dshell_channel.py
RENAMED
|
@@ -3,6 +3,7 @@ from re import search
|
|
|
3
3
|
from typing import Union
|
|
4
4
|
|
|
5
5
|
from discord import MISSING, PermissionOverwrite, Member, Role, Message
|
|
6
|
+
from discord.utils import _MissingSentinel
|
|
6
7
|
|
|
7
8
|
__all__ = [
|
|
8
9
|
'dshell_create_text_channel',
|
|
@@ -19,16 +20,29 @@ async def dshell_create_text_channel(ctx: Message,
|
|
|
19
20
|
category=None,
|
|
20
21
|
position=MISSING,
|
|
21
22
|
slowmode=MISSING,
|
|
22
|
-
topic=MISSING,
|
|
23
|
+
topic=MISSING,
|
|
24
|
+
nsfw=MISSING,
|
|
23
25
|
permission: dict[Union[Member, Role], PermissionOverwrite] = MISSING,
|
|
24
26
|
reason=None):
|
|
25
27
|
"""
|
|
26
28
|
Creates a text channel on the server
|
|
27
29
|
"""
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
if not isinstance(position, _MissingSentinel) and not isinstance(position, int):
|
|
32
|
+
raise Exception(f"Position must be an integer, not {type(position)} !")
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
if not isinstance(slowmode, _MissingSentinel) and not isinstance(slowmode, int):
|
|
35
|
+
raise Exception(f"Slowmode must be an integer, not {type(slowmode)} !")
|
|
36
|
+
|
|
37
|
+
if not isinstance(topic, _MissingSentinel) and not isinstance(topic, str):
|
|
38
|
+
raise Exception(f"Topic must be a string, not {type(topic)} !")
|
|
39
|
+
|
|
40
|
+
if not isinstance(nsfw, _MissingSentinel) and not isinstance(nsfw, bool):
|
|
41
|
+
raise Exception(f"NSFW must be a boolean, not {type(nsfw)} !")
|
|
42
|
+
|
|
43
|
+
channel_category = ctx.channel.category if category is None else ctx.channel.guild.get_channel(category)
|
|
44
|
+
|
|
45
|
+
created_channel = await ctx.guild.create_text_channel(str(name),
|
|
32
46
|
category=channel_category,
|
|
33
47
|
position=position,
|
|
34
48
|
slowmode_delay=slowmode,
|
|
@@ -39,6 +53,7 @@ async def dshell_create_text_channel(ctx: Message,
|
|
|
39
53
|
|
|
40
54
|
return created_channel.id
|
|
41
55
|
|
|
56
|
+
|
|
42
57
|
async def dshell_create_voice_channel(ctx: Message,
|
|
43
58
|
name,
|
|
44
59
|
category=None,
|
|
@@ -49,10 +64,15 @@ async def dshell_create_voice_channel(ctx: Message,
|
|
|
49
64
|
"""
|
|
50
65
|
Creates a voice channel on the server
|
|
51
66
|
"""
|
|
67
|
+
if not isinstance(position, _MissingSentinel) and not isinstance(position, int):
|
|
68
|
+
raise Exception(f"Position must be an integer, not {type(position)} !")
|
|
69
|
+
|
|
70
|
+
if not isinstance(bitrate, _MissingSentinel) and not isinstance(bitrate, int):
|
|
71
|
+
raise Exception(f"Bitrate must be an integer, not {type(bitrate)} !")
|
|
52
72
|
|
|
53
|
-
channel_category = ctx.channel.guild.get_channel(category)
|
|
73
|
+
channel_category = ctx.channel.category if category is None else ctx.channel.guild.get_channel(category)
|
|
54
74
|
|
|
55
|
-
created_channel = await ctx.guild.create_voice_channel(name,
|
|
75
|
+
created_channel = await ctx.guild.create_voice_channel(str(name),
|
|
56
76
|
category=channel_category,
|
|
57
77
|
position=position,
|
|
58
78
|
bitrate=bitrate,
|
|
@@ -67,6 +87,8 @@ async def dshell_delete_channel(ctx: Message, channel=None, reason=None, timeout
|
|
|
67
87
|
Deletes a channel.
|
|
68
88
|
You can add a waiting time before it is deleted (in seconds)
|
|
69
89
|
"""
|
|
90
|
+
if not isinstance(timeout, int):
|
|
91
|
+
raise Exception(f'Timeout must be an integer, not {type(timeout)} !')
|
|
70
92
|
|
|
71
93
|
channel_to_delete = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
72
94
|
|
|
@@ -85,6 +107,12 @@ async def dshell_delete_channels(ctx: Message, name=None, regex=None, reason=Non
|
|
|
85
107
|
Deletes all channels with the same name and/or matching the same regex.
|
|
86
108
|
If neither is set, it will delete all channels with the same name as the one where the command was executed.
|
|
87
109
|
"""
|
|
110
|
+
if name is not None and not isinstance(name, str):
|
|
111
|
+
raise Exception(f"Name must be a string, not {type(name)} !")
|
|
112
|
+
|
|
113
|
+
if regex is not None and not isinstance(regex, str):
|
|
114
|
+
raise Exception(f"Regex must be a string, not {type(regex)} !")
|
|
115
|
+
|
|
88
116
|
for channel in ctx.channel.guild.channels:
|
|
89
117
|
|
|
90
118
|
if name is not None and channel.name == str(name):
|
|
@@ -93,19 +121,32 @@ async def dshell_delete_channels(ctx: Message, name=None, regex=None, reason=Non
|
|
|
93
121
|
elif regex is not None and search(regex, channel.name):
|
|
94
122
|
await channel.delete(reason=reason)
|
|
95
123
|
|
|
124
|
+
|
|
96
125
|
async def dshell_edit_text_channel(ctx: Message,
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
126
|
+
channel=None,
|
|
127
|
+
name=None,
|
|
128
|
+
position=MISSING,
|
|
129
|
+
slowmode=MISSING,
|
|
130
|
+
topic=MISSING,
|
|
131
|
+
nsfw=MISSING,
|
|
132
|
+
permission: dict[Union[Member, Role], PermissionOverwrite] = MISSING,
|
|
133
|
+
reason=None):
|
|
105
134
|
"""
|
|
106
135
|
Edits a text channel on the server
|
|
107
136
|
"""
|
|
108
137
|
|
|
138
|
+
if not isinstance(position, _MissingSentinel) and not isinstance(position, int):
|
|
139
|
+
raise Exception(f"Position must be an integer, not {type(position)} !")
|
|
140
|
+
|
|
141
|
+
if not isinstance(slowmode, _MissingSentinel) and not isinstance(slowmode, int):
|
|
142
|
+
raise Exception(f"Slowmode must be an integer, not {type(slowmode)} !")
|
|
143
|
+
|
|
144
|
+
if not isinstance(topic, _MissingSentinel) and not isinstance(topic, str):
|
|
145
|
+
raise Exception(f"Topic must be a string, not {type(topic)} !")
|
|
146
|
+
|
|
147
|
+
if not isinstance(nsfw, _MissingSentinel) and not isinstance(nsfw, bool):
|
|
148
|
+
raise Exception(f"NSFW must be a boolean, not {type(nsfw)} !")
|
|
149
|
+
|
|
109
150
|
channel_to_edit = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
110
151
|
|
|
111
152
|
if channel_to_edit is None:
|
|
@@ -121,16 +162,22 @@ async def dshell_edit_text_channel(ctx: Message,
|
|
|
121
162
|
|
|
122
163
|
return channel_to_edit.id
|
|
123
164
|
|
|
165
|
+
|
|
124
166
|
async def dshell_edit_voice_channel(ctx: Message,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
167
|
+
channel=None,
|
|
168
|
+
name=None,
|
|
169
|
+
position=MISSING,
|
|
170
|
+
bitrate=MISSING,
|
|
171
|
+
permission: dict[Union[Member, Role], PermissionOverwrite] = MISSING,
|
|
172
|
+
reason=None):
|
|
131
173
|
"""
|
|
132
174
|
Edits a voice channel on the server
|
|
133
175
|
"""
|
|
176
|
+
if not isinstance(position, _MissingSentinel) and not isinstance(position, int):
|
|
177
|
+
raise Exception(f"Position must be an integer, not {type(position)} !")
|
|
178
|
+
|
|
179
|
+
if not isinstance(bitrate, _MissingSentinel) and not isinstance(bitrate, int):
|
|
180
|
+
raise Exception(f"Bitrate must be an integer, not {type(bitrate)} !")
|
|
134
181
|
|
|
135
182
|
channel_to_edit = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
136
183
|
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
from datetime import timedelta, datetime
|
|
2
|
+
|
|
3
|
+
from discord import MISSING, Message, Member, Permissions
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"dshell_ban_member",
|
|
7
|
+
"dshell_unban_member",
|
|
8
|
+
"dshell_kick_member",
|
|
9
|
+
"dshell_rename_member",
|
|
10
|
+
"dshell_add_roles",
|
|
11
|
+
"dshell_remove_roles",
|
|
12
|
+
"dshell_check_permissions",
|
|
13
|
+
"dshell_timeout_member",
|
|
14
|
+
"dshell_move_member"
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
async def dshell_ban_member(ctx: Message, member: int, reason: str = MISSING):
|
|
19
|
+
"""
|
|
20
|
+
Bans a member from the server.
|
|
21
|
+
"""
|
|
22
|
+
banned_member = ctx.channel.guild.get_member(member)
|
|
23
|
+
|
|
24
|
+
if not banned_member:
|
|
25
|
+
raise Exception(f'Member {member} not found in the server !')
|
|
26
|
+
|
|
27
|
+
await ctx.channel.guild.ban(banned_member, reason=reason)
|
|
28
|
+
|
|
29
|
+
return banned_member.id
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
async def dshell_unban_member(ctx: Message, user: int, reason: str = MISSING):
|
|
33
|
+
"""
|
|
34
|
+
Unbans a user from the server.
|
|
35
|
+
"""
|
|
36
|
+
banned_users = ctx.channel.guild.bans()
|
|
37
|
+
user_to_unban = None
|
|
38
|
+
|
|
39
|
+
async for ban_entry in banned_users:
|
|
40
|
+
if ban_entry.user.id == user:
|
|
41
|
+
user_to_unban = ban_entry.user
|
|
42
|
+
break
|
|
43
|
+
|
|
44
|
+
if not user_to_unban:
|
|
45
|
+
raise Exception(f'User {user} not found in the banned list')
|
|
46
|
+
|
|
47
|
+
await ctx.channel.guild.unban(user_to_unban, reason=reason)
|
|
48
|
+
|
|
49
|
+
return user_to_unban.id
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
async def dshell_kick_member(ctx: Message, member: int, reason: str = MISSING):
|
|
53
|
+
"""
|
|
54
|
+
Kicks a member from the server.
|
|
55
|
+
"""
|
|
56
|
+
kicked_member = ctx.channel.guild.get_member(member)
|
|
57
|
+
|
|
58
|
+
if not kicked_member:
|
|
59
|
+
raise Exception(f'Member {member} not found in the server !')
|
|
60
|
+
|
|
61
|
+
await ctx.channel.guild.kick(kicked_member, reason=reason)
|
|
62
|
+
|
|
63
|
+
return kicked_member.id
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
async def dshell_timeout_member(ctx: Message, duration: int, member=None, reason: str = MISSING):
|
|
67
|
+
"""
|
|
68
|
+
Timeouts a member in the server for a specified duration.
|
|
69
|
+
"""
|
|
70
|
+
target_member = ctx.author if member is None else ctx.channel.guild.get_member(member)
|
|
71
|
+
|
|
72
|
+
if not target_member:
|
|
73
|
+
raise Exception(f'Member {member} not found in the server !')
|
|
74
|
+
|
|
75
|
+
if not isinstance(duration, int):
|
|
76
|
+
raise TypeError("Duration must be an integer representing seconds.")
|
|
77
|
+
|
|
78
|
+
if duration < 0:
|
|
79
|
+
raise ValueError("Duration must be a non-negative integer.")
|
|
80
|
+
|
|
81
|
+
await target_member.timeout(until=datetime.now() + timedelta(seconds=duration), reason=reason)
|
|
82
|
+
|
|
83
|
+
return target_member.id
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
async def dshell_rename_member(ctx: Message, new_name, member=None):
|
|
87
|
+
"""
|
|
88
|
+
Renames a member in the server.
|
|
89
|
+
"""
|
|
90
|
+
renamed_member = ctx.channel.guild.get_member(member)
|
|
91
|
+
|
|
92
|
+
if not renamed_member:
|
|
93
|
+
raise Exception(f'Member {member} not found in the server !')
|
|
94
|
+
|
|
95
|
+
await renamed_member.edit(nick=new_name)
|
|
96
|
+
|
|
97
|
+
return renamed_member.id
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
async def dshell_add_roles(ctx: Message, roles: list[int] | int, member=None, reason: str = None):
|
|
101
|
+
"""
|
|
102
|
+
Adds roles to a member in the server.
|
|
103
|
+
"""
|
|
104
|
+
target_member: Member = ctx.author if member is None else ctx.channel.guild.get_member(member)
|
|
105
|
+
|
|
106
|
+
if not target_member:
|
|
107
|
+
raise Exception(f'Member {member} not found in the server !')
|
|
108
|
+
|
|
109
|
+
if isinstance(roles, int):
|
|
110
|
+
roles = [roles]
|
|
111
|
+
|
|
112
|
+
roles_to_add = [ctx.channel.guild.get_role(role_id) for role_id in roles if ctx.channel.guild.get_role(role_id)]
|
|
113
|
+
|
|
114
|
+
if not roles_to_add:
|
|
115
|
+
raise Exception(f'No role found !')
|
|
116
|
+
|
|
117
|
+
await target_member.add_roles(*roles_to_add, reason=reason)
|
|
118
|
+
|
|
119
|
+
return target_member.id
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
async def dshell_remove_roles(ctx: Message, roles: list[int] | int, member=None, reason: str = None):
|
|
123
|
+
"""
|
|
124
|
+
Removes roles from a member in the server.
|
|
125
|
+
"""
|
|
126
|
+
target_member: Member = ctx.author if member is None else ctx.channel.guild.get_member(member)
|
|
127
|
+
|
|
128
|
+
if not target_member:
|
|
129
|
+
raise Exception(f'Member {member} not found in the server !')
|
|
130
|
+
|
|
131
|
+
if isinstance(roles, int):
|
|
132
|
+
roles = [roles]
|
|
133
|
+
|
|
134
|
+
roles_to_remove = [ctx.channel.guild.get_role(role_id) for role_id in roles if ctx.channel.guild.get_role(role_id)]
|
|
135
|
+
|
|
136
|
+
if not roles_to_remove:
|
|
137
|
+
raise Exception(f'No role found !')
|
|
138
|
+
|
|
139
|
+
await target_member.remove_roles(*roles_to_remove, reason=reason)
|
|
140
|
+
|
|
141
|
+
return target_member.id
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
async def dshell_check_permissions(ctx: Message, permissions, member=None):
|
|
145
|
+
"""
|
|
146
|
+
Checks if a member has specific permissions in the server.
|
|
147
|
+
"""
|
|
148
|
+
target_member: Member = ctx.author if member is None else ctx.channel.guild.get_member(member)
|
|
149
|
+
|
|
150
|
+
if not target_member:
|
|
151
|
+
raise Exception(f'Member {member} not found in the server !')
|
|
152
|
+
|
|
153
|
+
if not isinstance(permissions, int):
|
|
154
|
+
raise TypeError("Permissions must be an integer representing permissions flags.")
|
|
155
|
+
|
|
156
|
+
permissions_to_check = Permissions(permissions)
|
|
157
|
+
member_permissions = target_member.guild_permissions
|
|
158
|
+
|
|
159
|
+
if (permissions_to_check.value & member_permissions.value) != 0:
|
|
160
|
+
return True
|
|
161
|
+
return False
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
async def dshell_move_member(ctx: Message, member=None, channel=None, disconnect: bool = False, reason=None):
|
|
165
|
+
"""
|
|
166
|
+
Moves a member to another channel.
|
|
167
|
+
If channel is None, disconnect the member from their current voice channel.
|
|
168
|
+
"""
|
|
169
|
+
target_member = ctx.author if member is None else ctx.channel.guild.get_member(member)
|
|
170
|
+
target_channel = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
171
|
+
|
|
172
|
+
if not target_member:
|
|
173
|
+
raise Exception(f'Member {member} not found in the server !')
|
|
174
|
+
|
|
175
|
+
if target_member.voice.channel is None:
|
|
176
|
+
raise Exception(f'Member {target_member.name} is not in a voice channel !')
|
|
177
|
+
|
|
178
|
+
if not target_channel:
|
|
179
|
+
raise Exception(f'Channel {channel} not found in the server !')
|
|
180
|
+
|
|
181
|
+
if disconnect:
|
|
182
|
+
await target_member.move_to(None, reason=reason)
|
|
183
|
+
else:
|
|
184
|
+
await target_member.move_to(target_channel, reason=reason)
|
|
185
|
+
|
|
186
|
+
return target_member.id
|
{dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/DISCORD_COMMANDS/dshell_message.py
RENAMED
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
from discord import Embed, Message
|
|
2
|
-
from discord.ext import commands
|
|
3
1
|
from re import search
|
|
4
2
|
|
|
3
|
+
from discord import Embed, Message
|
|
4
|
+
from discord.ext import commands
|
|
5
5
|
|
|
6
6
|
__all__ = [
|
|
7
7
|
'dshell_send_message',
|
|
8
8
|
'dshell_delete_message',
|
|
9
9
|
'dshell_purge_message',
|
|
10
10
|
'dshell_edit_message',
|
|
11
|
-
'
|
|
11
|
+
'dshell_get_hystory_messages',
|
|
12
12
|
'dshell_research_regex_in_content',
|
|
13
13
|
'dshell_add_reactions',
|
|
14
14
|
'dshell_remove_reactions'
|
|
15
15
|
]
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
async def dshell_send_message(ctx: Message, message=None, delete=None, channel=None, embeds=None
|
|
18
|
+
async def dshell_send_message(ctx: Message, message=None, delete=None, channel=None, embeds=None):
|
|
19
19
|
"""
|
|
20
20
|
Sends a message on Discord
|
|
21
21
|
"""
|
|
22
|
+
if delete is not None and not isinstance(delete, (int, float)):
|
|
23
|
+
raise Exception(f'Delete parameter must be a number (seconds) or None, not {type(delete)} !')
|
|
24
|
+
|
|
22
25
|
channel_to_send = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
23
26
|
|
|
24
27
|
if channel_to_send is None:
|
|
@@ -32,8 +35,8 @@ async def dshell_send_message(ctx: Message, message=None, delete=None, channel=N
|
|
|
32
35
|
elif isinstance(embeds, Embed):
|
|
33
36
|
embeds = ListNode([embeds])
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
embeds
|
|
38
|
+
else:
|
|
39
|
+
raise Exception(f'Embeds must be a list of Embed objects or a single Embed object, not {type(embeds)} !')
|
|
37
40
|
|
|
38
41
|
sended_message = await channel_to_send.send(message,
|
|
39
42
|
delete_after=delete,
|
|
@@ -47,7 +50,11 @@ async def dshell_delete_message(ctx: Message, message=None, reason=None, delay=0
|
|
|
47
50
|
Deletes a message
|
|
48
51
|
"""
|
|
49
52
|
|
|
50
|
-
delete_message = ctx if message is None else ctx.channel.get_partial_message(
|
|
53
|
+
delete_message = ctx if message is None else ctx.channel.get_partial_message(
|
|
54
|
+
message) # builds a reference to the message (even if it doesn't exist)
|
|
55
|
+
|
|
56
|
+
if not isinstance(delay, int):
|
|
57
|
+
raise Exception(f'Delete delay must be an integer, not {type(delay)} !')
|
|
51
58
|
|
|
52
59
|
if delay > 3600:
|
|
53
60
|
raise Exception(f'The message deletion delay is too long! ({delay} seconds)')
|
|
@@ -60,6 +67,9 @@ async def dshell_purge_message(ctx: Message, message_number, channel=None, reaso
|
|
|
60
67
|
Purges messages from a channel
|
|
61
68
|
"""
|
|
62
69
|
|
|
70
|
+
if not isinstance(message_number, int):
|
|
71
|
+
raise Exception(f'Message number must be an integer, not {type(message_number)} !')
|
|
72
|
+
|
|
63
73
|
purge_channel = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
64
74
|
|
|
65
75
|
if purge_channel is None:
|
|
@@ -72,7 +82,8 @@ async def dshell_edit_message(ctx: Message, message, new_content=None, embeds=No
|
|
|
72
82
|
"""
|
|
73
83
|
Edits a message
|
|
74
84
|
"""
|
|
75
|
-
edit_message = ctx.channel.get_partial_message(
|
|
85
|
+
edit_message = ctx.channel.get_partial_message(
|
|
86
|
+
message) # builds a reference to the message (even if it doesn't exist)
|
|
76
87
|
|
|
77
88
|
if embeds is None:
|
|
78
89
|
embeds = []
|
|
@@ -84,11 +95,15 @@ async def dshell_edit_message(ctx: Message, message, new_content=None, embeds=No
|
|
|
84
95
|
|
|
85
96
|
return edit_message.id
|
|
86
97
|
|
|
87
|
-
|
|
98
|
+
|
|
99
|
+
async def dshell_get_hystory_messages(ctx: Message, channel=None, limit=None):
|
|
88
100
|
"""
|
|
89
101
|
Searches for messages matching a regex in a channel
|
|
90
102
|
"""
|
|
91
103
|
|
|
104
|
+
if limit is not None and not isinstance(limit, int):
|
|
105
|
+
raise Exception(f"Limit must be an integer or None, not {type(limit)}!")
|
|
106
|
+
|
|
92
107
|
search_channel = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
93
108
|
|
|
94
109
|
if search_channel is None:
|
|
@@ -97,30 +112,35 @@ async def dshell_research_regex_message(ctx: Message, regex, channel=None):
|
|
|
97
112
|
from .._DshellParser.ast_nodes import ListNode
|
|
98
113
|
|
|
99
114
|
messages = ListNode([])
|
|
100
|
-
async for message in search_channel.history(limit=
|
|
101
|
-
|
|
102
|
-
messages.add(message)
|
|
115
|
+
async for message in search_channel.history(limit=limit):
|
|
116
|
+
messages.add(message)
|
|
103
117
|
|
|
104
118
|
if not messages:
|
|
105
|
-
raise commands.CommandError(f"No messages
|
|
119
|
+
raise commands.CommandError(f"No messages in {search_channel.mention}.")
|
|
106
120
|
|
|
107
121
|
return messages
|
|
108
122
|
|
|
123
|
+
|
|
109
124
|
async def dshell_research_regex_in_content(ctx: Message, regex, content=None):
|
|
110
125
|
"""
|
|
111
126
|
Searches for a regex in a specific message content
|
|
112
127
|
"""
|
|
113
128
|
|
|
114
|
-
if not
|
|
129
|
+
if not isinstance(regex, str):
|
|
130
|
+
raise Exception(f"Regex must be a string, not {type(regex)}!")
|
|
131
|
+
|
|
132
|
+
if not search(regex, str(content) if content is not None else ctx.content):
|
|
115
133
|
return False
|
|
116
134
|
|
|
117
135
|
return True
|
|
118
136
|
|
|
137
|
+
|
|
119
138
|
async def dshell_add_reactions(ctx: Message, reactions, message=None):
|
|
120
139
|
"""
|
|
121
140
|
Adds reactions to a message
|
|
122
141
|
"""
|
|
123
|
-
message = ctx if message is None else ctx.channel.get_partial_message(
|
|
142
|
+
message = ctx if message is None else ctx.channel.get_partial_message(
|
|
143
|
+
message) # builds a reference to the message (even if it doesn't exist)
|
|
124
144
|
|
|
125
145
|
if isinstance(reactions, str):
|
|
126
146
|
reactions = (reactions,)
|
|
@@ -130,11 +150,13 @@ async def dshell_add_reactions(ctx: Message, reactions, message=None):
|
|
|
130
150
|
|
|
131
151
|
return message.id
|
|
132
152
|
|
|
153
|
+
|
|
133
154
|
async def dshell_remove_reactions(ctx: Message, reactions, message=None):
|
|
134
155
|
"""
|
|
135
156
|
Removes reactions from a message
|
|
136
157
|
"""
|
|
137
|
-
message = ctx if message is None else ctx.channel.get_partial_message(
|
|
158
|
+
message = ctx if message is None else ctx.channel.get_partial_message(
|
|
159
|
+
message) # builds a reference to the message (even if it doesn't exist)
|
|
138
160
|
|
|
139
161
|
if isinstance(reactions, str):
|
|
140
162
|
reactions = [reactions]
|
|
@@ -142,4 +164,4 @@ async def dshell_remove_reactions(ctx: Message, reactions, message=None):
|
|
|
142
164
|
for reaction in reactions:
|
|
143
165
|
await message.clear_reaction(reaction)
|
|
144
166
|
|
|
145
|
-
return message.id
|
|
167
|
+
return message.id
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from discord import Message
|
|
2
|
+
from requests import get
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
'dshell_get_pastbin'
|
|
6
|
+
]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
async def dshell_get_pastbin(ctx: Message, code: str):
|
|
10
|
+
"""
|
|
11
|
+
Get a pastbin from a code snippet.
|
|
12
|
+
"""
|
|
13
|
+
if not isinstance(code, str):
|
|
14
|
+
raise Exception(f'Code must be a string, not {type(code)} !')
|
|
15
|
+
|
|
16
|
+
content = '' # Initialize content to an empty string
|
|
17
|
+
|
|
18
|
+
with get(f"https://pastebin.com/raw/{code}", stream=True, timeout=10) as response:
|
|
19
|
+
|
|
20
|
+
if not response.ok:
|
|
21
|
+
raise Exception(f"Failed to retrieve pastbin with code {code} !")
|
|
22
|
+
|
|
23
|
+
for line in response.iter_lines(decode_unicode=True, chunk_size=512):
|
|
24
|
+
len_content = len(content)
|
|
25
|
+
if line and len_content < 4000 and len_content + len(line) <= 4000:
|
|
26
|
+
content += line + '\n'
|
|
27
|
+
else:
|
|
28
|
+
break
|
|
29
|
+
|
|
30
|
+
return content
|
{dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/_DshellInterpreteur/dshell_interpreter.py
RENAMED
|
@@ -33,7 +33,24 @@ class DshellInterpreteur:
|
|
|
33
33
|
"""
|
|
34
34
|
self.ast: list[ASTNode] = parse(DshellTokenizer(code).start(), StartNode([]))[0]
|
|
35
35
|
self.env: dict[str, Any] = {
|
|
36
|
-
'__ret__': None
|
|
36
|
+
'__ret__': None, # environment variables, '__ret__' is used to store the return value of commands
|
|
37
|
+
'__guild__': ctx.channel.guild.name,
|
|
38
|
+
'__channel__': ctx.channel.name,
|
|
39
|
+
'__author__': ctx.author.name,
|
|
40
|
+
'__author_display_name__': ctx.author.display_name,
|
|
41
|
+
'__author_avatar__': ctx.author.display_avatar.url if ctx.author.display_avatar else None,
|
|
42
|
+
'__author_discriminator__': ctx.author.discriminator,
|
|
43
|
+
'__author_bot__': ctx.author.bot,
|
|
44
|
+
'__author_nick__': ctx.author.nick if hasattr(ctx.author, 'nick') else None,
|
|
45
|
+
'__author_avatar_url__': ctx.author.avatar.url if ctx.author.avatar else None,
|
|
46
|
+
'__author_id__': ctx.author.id,
|
|
47
|
+
'__message__': ctx.content,
|
|
48
|
+
'__message_id__': ctx.id,
|
|
49
|
+
'__channel_name__': ctx.channel.name,
|
|
50
|
+
'__channel_type__': ctx.channel.type.name if hasattr(ctx.channel, 'type') else None,
|
|
51
|
+
'__channel_id__': ctx.channel.id,
|
|
52
|
+
'__private_channel__': isinstance(ctx.channel, PrivateChannel),
|
|
53
|
+
}
|
|
37
54
|
self.vars = vars if vars is not None else ''
|
|
38
55
|
self.ctx: context = ctx
|
|
39
56
|
if debug:
|
|
@@ -71,7 +88,7 @@ class DshellInterpreteur:
|
|
|
71
88
|
elif_valid = False
|
|
72
89
|
if eval_expression(node.condition, self):
|
|
73
90
|
await self.execute(node.body)
|
|
74
|
-
|
|
91
|
+
continue
|
|
75
92
|
elif node.elif_nodes:
|
|
76
93
|
|
|
77
94
|
for i in node.elif_nodes:
|
|
@@ -170,12 +187,12 @@ def get_params(node: ParamNode, interpreter: DshellInterpreteur) -> dict[str, An
|
|
|
170
187
|
englobe_args = regrouped_args.pop('--*', {}) # get the arguments that are not mandatory
|
|
171
188
|
obligate = [i for i in regrouped_args.keys() if regrouped_args[i] == '*'] # get the obligatory parameters
|
|
172
189
|
|
|
173
|
-
|
|
174
190
|
g: list[list[Token]] = DshellTokenizer(interpreter.vars).start()
|
|
175
191
|
env_give_variables = regroupe_commandes(g[0], interpreter)[0] if g else {}
|
|
176
192
|
|
|
177
193
|
gived_variables = env_give_variables.pop('*', ()) # get the variables given in the environment
|
|
178
|
-
englobe_gived_variables: dict = env_give_variables.pop('--*',
|
|
194
|
+
englobe_gived_variables: dict = env_give_variables.pop('--*',
|
|
195
|
+
{}) # get the variables given in the environment that are not mandatory
|
|
179
196
|
|
|
180
197
|
for key, value in zip(regrouped_args.keys(), gived_variables):
|
|
181
198
|
regrouped_args[key] = value
|
|
@@ -187,7 +204,8 @@ def get_params(node: ParamNode, interpreter: DshellInterpreteur) -> dict[str, An
|
|
|
187
204
|
del englobe_args[key]
|
|
188
205
|
break
|
|
189
206
|
|
|
190
|
-
for key, englobe_gived_key, englobe_gived_value in zip(englobe_args.keys(), englobe_gived_variables.keys(),
|
|
207
|
+
for key, englobe_gived_key, englobe_gived_value in zip(englobe_args.keys(), englobe_gived_variables.keys(),
|
|
208
|
+
englobe_gived_variables.values()):
|
|
191
209
|
if key == englobe_gived_key:
|
|
192
210
|
regrouped_args[key] = englobe_gived_value
|
|
193
211
|
|
|
@@ -203,10 +221,9 @@ def get_params(node: ParamNode, interpreter: DshellInterpreteur) -> dict[str, An
|
|
|
203
221
|
if regrouped_args[key] == '*':
|
|
204
222
|
raise Exception(f"'{key}' is an obligatory parameter, but no value was given for it.")
|
|
205
223
|
|
|
206
|
-
print(regrouped_args)
|
|
207
|
-
|
|
208
224
|
return regrouped_args
|
|
209
225
|
|
|
226
|
+
|
|
210
227
|
def eval_expression_inline(if_node: IfNode, interpreter: DshellInterpreteur) -> Token:
|
|
211
228
|
"""
|
|
212
229
|
Eval a conditional expression inline.
|
|
@@ -312,7 +329,7 @@ def regroupe_commandes(body: list[Token], interpreter: DshellInterpreteur) -> li
|
|
|
312
329
|
type_=DTT.SEPARATOR, value=body[i].value, position=body[i].position)
|
|
313
330
|
] + body[i + 1:], interpreter
|
|
314
331
|
) # add a sub-dictionary for sub-commands
|
|
315
|
-
#return list_tokens
|
|
332
|
+
# return list_tokens
|
|
316
333
|
|
|
317
334
|
elif (body[i].type == DTT.SEPARATOR and
|
|
318
335
|
(body[i + 1].type == DTT.MATHS_OPERATOR and body[i + 1].value == '*') and
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
from typing import Optional, Any
|
|
2
1
|
from random import randint
|
|
2
|
+
from typing import Optional, Any
|
|
3
3
|
|
|
4
4
|
from .._DshellTokenizer.dshell_token_type import Token
|
|
5
5
|
|
|
@@ -35,6 +35,7 @@ class StartNode(ASTNode):
|
|
|
35
35
|
"""
|
|
36
36
|
Node representing the start of the AST.
|
|
37
37
|
"""
|
|
38
|
+
|
|
38
39
|
def __init__(self, body: list):
|
|
39
40
|
self.body = body
|
|
40
41
|
|
|
@@ -56,6 +57,7 @@ class ElseNode(ASTNode):
|
|
|
56
57
|
"""
|
|
57
58
|
Node representing the 'else' part of an if statement.
|
|
58
59
|
"""
|
|
60
|
+
|
|
59
61
|
def __init__(self, body: list[Token]):
|
|
60
62
|
"""
|
|
61
63
|
:param body: list of tokens representing the body of the else statement
|
|
@@ -80,6 +82,7 @@ class ElifNode(ASTNode):
|
|
|
80
82
|
"""
|
|
81
83
|
Node representing an 'elif' part of an if statement.
|
|
82
84
|
"""
|
|
85
|
+
|
|
83
86
|
def __init__(self, condition: list[Token], body: list[Token], parent: "IfNode"):
|
|
84
87
|
"""
|
|
85
88
|
:param condition: list of tokens representing the condition for the elif
|
|
@@ -110,6 +113,7 @@ class IfNode(ASTNode):
|
|
|
110
113
|
"""
|
|
111
114
|
Node representing an 'if' statement, which can contain 'elif' and 'else' parts.
|
|
112
115
|
"""
|
|
116
|
+
|
|
113
117
|
def __init__(self, condition: list[Token], body: list[Token], elif_nodes: Optional[list[ElifNode]] = None,
|
|
114
118
|
else_body: Optional[ElseNode] = None):
|
|
115
119
|
"""
|
|
@@ -141,10 +145,12 @@ class IfNode(ASTNode):
|
|
|
141
145
|
"id": self.id
|
|
142
146
|
}
|
|
143
147
|
|
|
148
|
+
|
|
144
149
|
class LoopNode(ASTNode):
|
|
145
150
|
"""
|
|
146
151
|
Node representing a loop structure in the AST.
|
|
147
152
|
"""
|
|
153
|
+
|
|
148
154
|
def __init__(self, variable: "VarNode", body: list):
|
|
149
155
|
"""
|
|
150
156
|
:param variable: VarNode representing the loop variable. This variable will be used to iterate over the body. Can contain a ListNode, string or integer.
|
|
@@ -167,10 +173,12 @@ class LoopNode(ASTNode):
|
|
|
167
173
|
"body": [token.to_dict() for token in self.body]
|
|
168
174
|
}
|
|
169
175
|
|
|
176
|
+
|
|
170
177
|
class ArgsCommandNode(ASTNode):
|
|
171
178
|
"""
|
|
172
179
|
Node representing the arguments of a command in the AST.
|
|
173
180
|
"""
|
|
181
|
+
|
|
174
182
|
def __init__(self, body: list[Token]):
|
|
175
183
|
"""
|
|
176
184
|
:param body: list of tokens representing the arguments of the command
|
|
@@ -195,6 +203,7 @@ class CommandNode(ASTNode):
|
|
|
195
203
|
"""
|
|
196
204
|
Node representing a command in the AST.
|
|
197
205
|
"""
|
|
206
|
+
|
|
198
207
|
def __init__(self, name: str, body: ArgsCommandNode):
|
|
199
208
|
"""
|
|
200
209
|
:param name: The command name (e.g., "sm", "cc")
|
|
@@ -222,6 +231,7 @@ class VarNode(ASTNode):
|
|
|
222
231
|
"""
|
|
223
232
|
Node representing a variable declaration in the AST.
|
|
224
233
|
"""
|
|
234
|
+
|
|
225
235
|
def __init__(self, name: Token, body: list[Token]):
|
|
226
236
|
"""
|
|
227
237
|
:param name: Token representing the variable name
|
|
@@ -249,6 +259,7 @@ class EndNode(ASTNode):
|
|
|
249
259
|
"""
|
|
250
260
|
Node representing the end of the AST.
|
|
251
261
|
"""
|
|
262
|
+
|
|
252
263
|
def __init__(self):
|
|
253
264
|
pass
|
|
254
265
|
|
|
@@ -269,6 +280,7 @@ class FieldEmbedNode(ASTNode):
|
|
|
269
280
|
"""
|
|
270
281
|
Node representing a field in an embed structure.
|
|
271
282
|
"""
|
|
283
|
+
|
|
272
284
|
def __init__(self, body: list[Token]):
|
|
273
285
|
"""
|
|
274
286
|
:param body: list of tokens representing the field content
|
|
@@ -293,6 +305,7 @@ class EmbedNode(ASTNode):
|
|
|
293
305
|
"""
|
|
294
306
|
Node representing an embed structure in the AST.
|
|
295
307
|
"""
|
|
308
|
+
|
|
296
309
|
def __init__(self, body: list[Token], fields: list[FieldEmbedNode]):
|
|
297
310
|
"""
|
|
298
311
|
:param body: list of tokens representing the embed content
|
|
@@ -320,6 +333,7 @@ class PermissionNode(ASTNode):
|
|
|
320
333
|
"""
|
|
321
334
|
Node representing a permission structure in the AST.
|
|
322
335
|
"""
|
|
336
|
+
|
|
323
337
|
def __init__(self, body: list[Token]):
|
|
324
338
|
"""
|
|
325
339
|
:param body: list of tokens representing the permission content
|
|
@@ -344,6 +358,7 @@ class SleepNode(ASTNode):
|
|
|
344
358
|
"""
|
|
345
359
|
Node representing a sleep command in the AST.
|
|
346
360
|
"""
|
|
361
|
+
|
|
347
362
|
def __init__(self, body: list[Token]):
|
|
348
363
|
"""
|
|
349
364
|
:param body: list of tokens representing the sleep duration
|
|
@@ -396,6 +411,7 @@ class IdentOperationNode(ASTNode):
|
|
|
396
411
|
"args": self.args.to_dict()
|
|
397
412
|
}
|
|
398
413
|
|
|
414
|
+
|
|
399
415
|
class ParamNode(ASTNode):
|
|
400
416
|
"""
|
|
401
417
|
Node representing a parameter in the AST.
|
|
@@ -423,6 +439,7 @@ class ParamNode(ASTNode):
|
|
|
423
439
|
"body": [token.to_dict() for token in self.body]
|
|
424
440
|
}
|
|
425
441
|
|
|
442
|
+
|
|
426
443
|
class ListNode(ASTNode):
|
|
427
444
|
"""
|
|
428
445
|
Node representing a list structure in the AST.
|
|
@@ -7,7 +7,7 @@ __all__ = [
|
|
|
7
7
|
"ast_to_dict",
|
|
8
8
|
]
|
|
9
9
|
|
|
10
|
-
from typing import Union
|
|
10
|
+
from typing import Union
|
|
11
11
|
|
|
12
12
|
from .ast_nodes import (ASTNode,
|
|
13
13
|
CommandNode,
|
|
@@ -25,11 +25,10 @@ from .ast_nodes import (ASTNode,
|
|
|
25
25
|
PermissionNode,
|
|
26
26
|
ParamNode,
|
|
27
27
|
StartNode)
|
|
28
|
+
from .._DshellTokenizer import dshell_operators
|
|
28
29
|
from .._DshellTokenizer.dshell_token_type import DshellTokenType as DTT
|
|
29
30
|
from .._DshellTokenizer.dshell_token_type import Token
|
|
30
31
|
|
|
31
|
-
from .._DshellTokenizer import dshell_operators
|
|
32
|
-
|
|
33
32
|
|
|
34
33
|
def parse(token_lines: list[list[Token]], start_node: ASTNode) -> tuple[list[ASTNode], int]:
|
|
35
34
|
"""
|
|
@@ -213,6 +212,7 @@ elif first_token_line.type == DTT.LIST: # si le token est une liste (qui comport
|
|
|
213
212
|
last_block.body.append(list_node)
|
|
214
213
|
"""
|
|
215
214
|
|
|
215
|
+
|
|
216
216
|
def ast_to_dict(obj):
|
|
217
217
|
if isinstance(obj, list):
|
|
218
218
|
return [ast_to_dict(item) for item in obj]
|
|
@@ -221,6 +221,7 @@ def ast_to_dict(obj):
|
|
|
221
221
|
else:
|
|
222
222
|
return obj # fallback for primitives or tokens
|
|
223
223
|
|
|
224
|
+
|
|
224
225
|
def dict_to_ast(data):
|
|
225
226
|
"""
|
|
226
227
|
Convertit un dictionnaire en une structure AST.
|
|
@@ -232,6 +233,7 @@ def dict_to_ast(data):
|
|
|
232
233
|
elif isinstance(data, dict):
|
|
233
234
|
pass
|
|
234
235
|
|
|
236
|
+
|
|
235
237
|
def parser_inline(tokens: list[Token]) -> tuple[list[list[Token]], bool]:
|
|
236
238
|
"""
|
|
237
239
|
Transforme une ligne avec un if/else inline en structure multilignes
|
{dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/_DshellTokenizer/dshell_keywords.py
RENAMED
|
@@ -10,8 +10,9 @@ __all__ = [
|
|
|
10
10
|
from typing import Callable
|
|
11
11
|
|
|
12
12
|
from ..DISCORD_COMMANDS.dshell_channel import *
|
|
13
|
-
from ..DISCORD_COMMANDS.dshell_message import *
|
|
14
13
|
from ..DISCORD_COMMANDS.dshell_member import *
|
|
14
|
+
from ..DISCORD_COMMANDS.dshell_message import *
|
|
15
|
+
from ..DISCORD_COMMANDS.dshell_pastbin import *
|
|
15
16
|
|
|
16
17
|
dshell_keyword: set[str] = {
|
|
17
18
|
'if', 'else', 'elif', 'loop', '#end', 'var', '#loop', '#if', 'sleep', 'param', '#param'
|
|
@@ -22,6 +23,8 @@ dshell_discord_keyword: set[str] = {
|
|
|
22
23
|
}
|
|
23
24
|
dshell_commands: dict[str, Callable] = {
|
|
24
25
|
|
|
26
|
+
"gp": dshell_get_pastbin, # get pastbin
|
|
27
|
+
|
|
25
28
|
"sm": dshell_send_message, # send message
|
|
26
29
|
"dm": dshell_delete_message,
|
|
27
30
|
"pm": dshell_purge_message,
|
|
@@ -30,14 +33,17 @@ dshell_commands: dict[str, Callable] = {
|
|
|
30
33
|
"cc": dshell_create_text_channel, # create channel
|
|
31
34
|
"cvc": dshell_create_voice_channel, # create voice channel
|
|
32
35
|
"dc": dshell_delete_channel, # delete channel
|
|
33
|
-
"dcs": dshell_delete_channels,
|
|
36
|
+
"dcs": dshell_delete_channels, # delete several channels by name or regex
|
|
34
37
|
|
|
35
38
|
"bm": dshell_ban_member, # ban member
|
|
36
39
|
"um": dshell_unban_member, # unban member
|
|
37
40
|
"km": dshell_kick_member, # kick member
|
|
41
|
+
"tm": dshell_timeout_member, # timeout member
|
|
42
|
+
"mm": dshell_move_member, # move member to another channel
|
|
38
43
|
"rm": dshell_rename_member, # rename member
|
|
44
|
+
"cp": dshell_check_permissions, # check permissions
|
|
39
45
|
|
|
40
|
-
"
|
|
46
|
+
"ghm": dshell_get_hystory_messages, # research regex in message
|
|
41
47
|
"src": dshell_research_regex_in_content, # research regex in content
|
|
42
48
|
|
|
43
49
|
"ec": dshell_edit_text_channel, # edit text channel
|
|
@@ -6,6 +6,7 @@ Dshell/DISCORD_COMMANDS/__init__.py
|
|
|
6
6
|
Dshell/DISCORD_COMMANDS/dshell_channel.py
|
|
7
7
|
Dshell/DISCORD_COMMANDS/dshell_member.py
|
|
8
8
|
Dshell/DISCORD_COMMANDS/dshell_message.py
|
|
9
|
+
Dshell/DISCORD_COMMANDS/dshell_pastbin.py
|
|
9
10
|
Dshell/_DshellInterpreteur/__init__.py
|
|
10
11
|
Dshell/_DshellInterpreteur/dshell_interpreter.py
|
|
11
12
|
Dshell/_DshellParser/__init__.py
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
from discord import MISSING, Message, Member
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
__all__ = [
|
|
5
|
-
"dshell_ban_member",
|
|
6
|
-
"dshell_unban_member",
|
|
7
|
-
"dshell_kick_member",
|
|
8
|
-
"dshell_rename_member",
|
|
9
|
-
"dshell_add_roles",
|
|
10
|
-
"dshell_remove_roles",
|
|
11
|
-
]
|
|
12
|
-
|
|
13
|
-
async def dshell_ban_member(ctx: Message, member: int, reason: str = MISSING):
|
|
14
|
-
"""
|
|
15
|
-
Bans a member from the server.
|
|
16
|
-
"""
|
|
17
|
-
banned_member = ctx.channel.guild.get_member(member)
|
|
18
|
-
|
|
19
|
-
if not banned_member:
|
|
20
|
-
return 1 # Member not found in the server
|
|
21
|
-
|
|
22
|
-
await ctx.channel.guild.ban(banned_member, reason=reason)
|
|
23
|
-
|
|
24
|
-
return banned_member.id
|
|
25
|
-
|
|
26
|
-
async def dshell_unban_member(ctx: Message, user: int, reason: str = MISSING):
|
|
27
|
-
"""
|
|
28
|
-
Unbans a user from the server.
|
|
29
|
-
"""
|
|
30
|
-
banned_users = ctx.channel.guild.bans()
|
|
31
|
-
user_to_unban = None
|
|
32
|
-
|
|
33
|
-
async for ban_entry in banned_users:
|
|
34
|
-
if ban_entry.user.id == user:
|
|
35
|
-
user_to_unban = ban_entry.user
|
|
36
|
-
break
|
|
37
|
-
|
|
38
|
-
if not user_to_unban:
|
|
39
|
-
return 1 # User not found in the banned list
|
|
40
|
-
|
|
41
|
-
await ctx.channel.guild.unban(user_to_unban, reason=reason)
|
|
42
|
-
|
|
43
|
-
return user_to_unban.id
|
|
44
|
-
|
|
45
|
-
async def dshell_kick_member(ctx: Message, member: int, reason: str = MISSING):
|
|
46
|
-
"""
|
|
47
|
-
Kicks a member from the server.
|
|
48
|
-
"""
|
|
49
|
-
kicked_member = ctx.channel.guild.get_member(member)
|
|
50
|
-
|
|
51
|
-
if not kicked_member:
|
|
52
|
-
return 1 # Member not found in the server
|
|
53
|
-
|
|
54
|
-
await ctx.channel.guild.kick(kicked_member, reason=reason)
|
|
55
|
-
|
|
56
|
-
return kicked_member.id
|
|
57
|
-
|
|
58
|
-
async def dshell_rename_member(ctx: Message, new_name, member=None):
|
|
59
|
-
"""
|
|
60
|
-
Renames a member in the server.
|
|
61
|
-
"""
|
|
62
|
-
renamed_member = ctx.channel.guild.get_member(member)
|
|
63
|
-
|
|
64
|
-
if not renamed_member:
|
|
65
|
-
return 1 # Member not found in the server
|
|
66
|
-
|
|
67
|
-
await renamed_member.edit(nick=new_name)
|
|
68
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/_DshellTokenizer/dshell_token_type.py
RENAMED
|
File without changes
|
{dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/Dshell/_DshellTokenizer/dshell_tokenizer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/dshellInterpreter.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{dshellinterpreter-0.2.1 → dshellinterpreter-0.2.3}/dshellInterpreter.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|