dshellInterpreter 0.2.22.1__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.
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/__init__.py +8 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/dshell_channel.py +623 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/dshell_embed.py +68 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/dshell_interaction.py +90 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/dshell_member.py +283 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/dshell_message.py +444 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/dshell_pastbin.py +27 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/dshell_role.py +124 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/dshell_ui.py +130 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/utils/__init__.py +8 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/utils/utils_global.py +196 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/utils/utils_list.py +104 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/utils/utils_member.py +32 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/utils/utils_message.py +81 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/utils/utils_permissions.py +101 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/utils/utils_string.py +156 -0
- dshellinterpreter-0.2.22.1/Dshell/DISCORD_COMMANDS/utils/utils_thread.py +37 -0
- dshellinterpreter-0.2.22.1/Dshell/_DshellInterpreteur/__init__.py +4 -0
- dshellinterpreter-0.2.22.1/Dshell/_DshellInterpreteur/cached_messages.py +4 -0
- dshellinterpreter-0.2.22.1/Dshell/_DshellInterpreteur/dshell_arguments.py +77 -0
- dshellinterpreter-0.2.22.1/Dshell/_DshellInterpreteur/dshell_interpreter.py +311 -0
- dshellinterpreter-0.2.22.1/Dshell/_DshellInterpreteur/errors.py +8 -0
- dshellinterpreter-0.2.22.1/Dshell/_DshellInterpreteur/utils_interpreter.py +206 -0
- dshellinterpreter-0.2.22.1/Dshell/_DshellParser/__init__.py +2 -0
- dshellinterpreter-0.2.22.1/Dshell/_DshellParser/ast_nodes.py +699 -0
- dshellinterpreter-0.2.22.1/Dshell/_DshellParser/dshell_parser.py +429 -0
- dshellinterpreter-0.2.22.1/Dshell/_DshellTokenizer/__init__.py +4 -0
- dshellinterpreter-0.2.22.1/Dshell/_DshellTokenizer/dshell_keywords.py +185 -0
- dshellinterpreter-0.2.22.1/Dshell/_DshellTokenizer/dshell_token_type.py +55 -0
- dshellinterpreter-0.2.22.1/Dshell/_DshellTokenizer/dshell_tokenizer.py +158 -0
- dshellinterpreter-0.2.22.1/Dshell/__init__.py +3 -0
- dshellinterpreter-0.2.22.1/Dshell/full_import.py +16 -0
- dshellinterpreter-0.2.22.1/LICENSE +21 -0
- dshellinterpreter-0.2.22.1/PKG-INFO +36 -0
- dshellinterpreter-0.2.22.1/README.md +3 -0
- dshellinterpreter-0.2.22.1/dshellInterpreter.egg-info/PKG-INFO +36 -0
- dshellinterpreter-0.2.22.1/dshellInterpreter.egg-info/SOURCES.txt +40 -0
- dshellinterpreter-0.2.22.1/dshellInterpreter.egg-info/dependency_links.txt +1 -0
- dshellinterpreter-0.2.22.1/dshellInterpreter.egg-info/requires.txt +3 -0
- dshellinterpreter-0.2.22.1/dshellInterpreter.egg-info/top_level.txt +1 -0
- dshellinterpreter-0.2.22.1/setup.cfg +4 -0
- dshellinterpreter-0.2.22.1/setup.py +33 -0
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
from Dshell.full_import import (Message,
|
|
2
|
+
MISSING,
|
|
3
|
+
_MissingSentinel,
|
|
4
|
+
Member,
|
|
5
|
+
Role,
|
|
6
|
+
PermissionOverwrite,
|
|
7
|
+
CategoryChannel,
|
|
8
|
+
VoiceChannel,
|
|
9
|
+
PartialMessage)
|
|
10
|
+
|
|
11
|
+
from .._DshellParser.ast_nodes import ListNode
|
|
12
|
+
|
|
13
|
+
from Dshell.full_import import search
|
|
14
|
+
|
|
15
|
+
from Dshell.full_import import sleep
|
|
16
|
+
|
|
17
|
+
from Dshell.full_import import Union
|
|
18
|
+
|
|
19
|
+
from .utils.utils_message import utils_get_message
|
|
20
|
+
from .utils.utils_thread import utils_get_thread
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
'dshell_get_channel',
|
|
24
|
+
'dshell_get_channels',
|
|
25
|
+
'dshell_get_thread',
|
|
26
|
+
'dshell_get_channels_in_category',
|
|
27
|
+
'dshell_create_text_channel',
|
|
28
|
+
'dshell_create_thread_message',
|
|
29
|
+
'dshell_delete_channel',
|
|
30
|
+
'dshell_delete_channels',
|
|
31
|
+
'dshell_delete_thread',
|
|
32
|
+
'dshell_create_voice_channel',
|
|
33
|
+
'dshell_edit_text_channel',
|
|
34
|
+
'dshell_edit_voice_channel',
|
|
35
|
+
'dshell_edit_thread',
|
|
36
|
+
'dshell_create_category',
|
|
37
|
+
'dshell_edit_category',
|
|
38
|
+
'dshell_delete_category',
|
|
39
|
+
'dshell_get_channel_category_id',
|
|
40
|
+
'dshell_get_channel_nsfw',
|
|
41
|
+
'dshell_get_channel_slowmode',
|
|
42
|
+
'dshell_get_channel_topic',
|
|
43
|
+
'dshell_get_channel_threads',
|
|
44
|
+
'dshell_get_channel_position',
|
|
45
|
+
'dshell_get_channel_url',
|
|
46
|
+
'dshell_get_channel_voice_members',
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
async def dshell_get_channel(ctx: Message, name):
|
|
51
|
+
"""
|
|
52
|
+
Returns the channel object of the channel where the command was executed or the specified channel.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
if isinstance(name, str):
|
|
56
|
+
return next((c.id for c in ctx.channel.guild.channels if c.name == name), None)
|
|
57
|
+
|
|
58
|
+
raise Exception(f"Channel must be an integer or a string, not {type(name)} !")
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
async def dshell_get_channels(ctx: Message, name=None, regex=None):
|
|
62
|
+
"""
|
|
63
|
+
Returns a list of channels with the same name and/or matching the same regex.
|
|
64
|
+
If neither is set, it will return all channels in the server.
|
|
65
|
+
"""
|
|
66
|
+
if name is not None and not isinstance(name, str):
|
|
67
|
+
raise Exception(f"Name must be a string, not {type(name)} !")
|
|
68
|
+
|
|
69
|
+
if regex is not None and not isinstance(regex, str):
|
|
70
|
+
raise Exception(f"Regex must be a string, not {type(regex)} !")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
channels = ListNode([])
|
|
74
|
+
|
|
75
|
+
for channel in ctx.channel.guild.channels:
|
|
76
|
+
if name is not None and channel.name == str(name):
|
|
77
|
+
channels.add(channel.id)
|
|
78
|
+
|
|
79
|
+
elif regex is not None and search(regex, channel.name):
|
|
80
|
+
channels.add(channel.id)
|
|
81
|
+
|
|
82
|
+
return channels
|
|
83
|
+
|
|
84
|
+
async def dshell_get_channels_in_category(ctx: Message, category=None, name=None, regex=None):
|
|
85
|
+
"""
|
|
86
|
+
Returns a list of channels in a specific category with the same name and/or matching the same regex.
|
|
87
|
+
If neither is set, it will return all channels in the specified category.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
if category is None and ctx.channel.category is not None:
|
|
91
|
+
category = ctx.channel.category.id
|
|
92
|
+
|
|
93
|
+
if category is None:
|
|
94
|
+
raise Exception("Category must be specified !")
|
|
95
|
+
|
|
96
|
+
if not isinstance(category, int):
|
|
97
|
+
raise Exception(f"Category must be an integer, not {type(category)} !")
|
|
98
|
+
|
|
99
|
+
if name is not None and not isinstance(name, str):
|
|
100
|
+
raise Exception(f"Name must be a string, not {type(name)} !")
|
|
101
|
+
|
|
102
|
+
if regex is not None and not isinstance(regex, str):
|
|
103
|
+
raise Exception(f"Regex must be a string, not {type(regex)} !")
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
channels = ListNode([])
|
|
107
|
+
|
|
108
|
+
category_channel = ctx.channel.guild.get_channel(category)
|
|
109
|
+
if category_channel is None or not hasattr(category_channel, 'channels'):
|
|
110
|
+
raise Exception(f"Category {category} not found or does not contain channels !")
|
|
111
|
+
|
|
112
|
+
for channel in category_channel.channels:
|
|
113
|
+
if name is not None and channel.name == str(name):
|
|
114
|
+
channels.add(channel.id)
|
|
115
|
+
|
|
116
|
+
elif regex is not None and search(regex, channel.name):
|
|
117
|
+
channels.add(channel.id)
|
|
118
|
+
|
|
119
|
+
return channels
|
|
120
|
+
|
|
121
|
+
async def dshell_create_text_channel(ctx: Message,
|
|
122
|
+
name,
|
|
123
|
+
category=None,
|
|
124
|
+
position=MISSING,
|
|
125
|
+
slowmode=MISSING,
|
|
126
|
+
topic=MISSING,
|
|
127
|
+
nsfw=MISSING,
|
|
128
|
+
permissions: dict[Union[Member, Role], PermissionOverwrite] = MISSING,
|
|
129
|
+
reason=None):
|
|
130
|
+
"""
|
|
131
|
+
Creates a text channel on the server
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
if not isinstance(position, (_MissingSentinel, int)):
|
|
135
|
+
raise Exception(f"Position must be an integer, not {type(position)} !")
|
|
136
|
+
|
|
137
|
+
if not isinstance(slowmode, (_MissingSentinel, int)):
|
|
138
|
+
raise Exception(f"Slowmode must be an integer, not {type(slowmode)} !")
|
|
139
|
+
|
|
140
|
+
if not isinstance(topic, (_MissingSentinel, str)):
|
|
141
|
+
raise Exception(f"Topic must be a string, not {type(topic)} !")
|
|
142
|
+
|
|
143
|
+
if not isinstance(nsfw, (_MissingSentinel, bool)):
|
|
144
|
+
raise Exception(f"NSFW must be a boolean, not {type(nsfw)} !")
|
|
145
|
+
|
|
146
|
+
channel_category = ctx.channel.category if category is None else ctx.channel.guild.get_channel(category)
|
|
147
|
+
|
|
148
|
+
created_channel = await ctx.guild.create_text_channel(str(name),
|
|
149
|
+
category=channel_category,
|
|
150
|
+
position=position,
|
|
151
|
+
slowmode_delay=slowmode,
|
|
152
|
+
topic=topic,
|
|
153
|
+
nsfw=nsfw,
|
|
154
|
+
overwrites=permissions,
|
|
155
|
+
reason=reason)
|
|
156
|
+
|
|
157
|
+
return created_channel.id
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
async def dshell_create_voice_channel(ctx: Message,
|
|
161
|
+
name,
|
|
162
|
+
category=None,
|
|
163
|
+
position=MISSING,
|
|
164
|
+
bitrate=MISSING,
|
|
165
|
+
permissions: dict[Union[Member, Role], PermissionOverwrite] = MISSING,
|
|
166
|
+
reason=None):
|
|
167
|
+
"""
|
|
168
|
+
Creates a voice channel on the server
|
|
169
|
+
"""
|
|
170
|
+
if not isinstance(position, (_MissingSentinel, int)):
|
|
171
|
+
raise Exception(f"Position must be an integer, not {type(position)} !")
|
|
172
|
+
|
|
173
|
+
if not isinstance(bitrate, (_MissingSentinel, int)):
|
|
174
|
+
raise Exception(f"Bitrate must be an integer, not {type(bitrate)} !")
|
|
175
|
+
|
|
176
|
+
channel_category = ctx.channel.category if category is None else ctx.channel.guild.get_channel(category)
|
|
177
|
+
|
|
178
|
+
created_channel = await ctx.guild.create_voice_channel(str(name),
|
|
179
|
+
category=channel_category,
|
|
180
|
+
position=position,
|
|
181
|
+
bitrate=bitrate,
|
|
182
|
+
overwrites=permissions,
|
|
183
|
+
reason=reason)
|
|
184
|
+
|
|
185
|
+
return created_channel.id
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
async def dshell_delete_channel(ctx: Message, channel=None, reason=None, timeout=0):
|
|
189
|
+
"""
|
|
190
|
+
Deletes a channel.
|
|
191
|
+
You can add a waiting time before it is deleted (in seconds)
|
|
192
|
+
"""
|
|
193
|
+
if not isinstance(timeout, int):
|
|
194
|
+
raise Exception(f'Timeout must be an integer, not {type(timeout)} !')
|
|
195
|
+
|
|
196
|
+
channel_to_delete = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
197
|
+
|
|
198
|
+
if channel_to_delete is None:
|
|
199
|
+
raise Exception(f"Channel {channel} not found !")
|
|
200
|
+
|
|
201
|
+
await sleep(timeout)
|
|
202
|
+
|
|
203
|
+
await channel_to_delete.delete(reason=reason)
|
|
204
|
+
|
|
205
|
+
return channel_to_delete.id
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
async def dshell_delete_channels(ctx: Message, name=None, regex=None, reason=None):
|
|
209
|
+
"""
|
|
210
|
+
Deletes all channels with the same name and/or matching the same regex.
|
|
211
|
+
If neither is set, it will delete all channels with the same name as the one where the command was executed.
|
|
212
|
+
"""
|
|
213
|
+
if name is not None and not isinstance(name, str):
|
|
214
|
+
raise Exception(f"Name must be a string, not {type(name)} !")
|
|
215
|
+
|
|
216
|
+
if regex is not None and not isinstance(regex, str):
|
|
217
|
+
raise Exception(f"Regex must be a string, not {type(regex)} !")
|
|
218
|
+
|
|
219
|
+
for channel in ctx.channel.guild.channels:
|
|
220
|
+
|
|
221
|
+
if name is not None and channel.name == str(name):
|
|
222
|
+
await channel.delete(reason=reason)
|
|
223
|
+
|
|
224
|
+
elif regex is not None and search(regex, channel.name):
|
|
225
|
+
await channel.delete(reason=reason)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
async def dshell_edit_text_channel(ctx: Message,
|
|
229
|
+
channel=None,
|
|
230
|
+
name=None,
|
|
231
|
+
category=MISSING,
|
|
232
|
+
position=MISSING,
|
|
233
|
+
slowmode=MISSING,
|
|
234
|
+
topic=MISSING,
|
|
235
|
+
nsfw=MISSING,
|
|
236
|
+
permissions: dict[Union[Member, Role], PermissionOverwrite] = MISSING,
|
|
237
|
+
reason=None):
|
|
238
|
+
"""
|
|
239
|
+
Edits a text channel on the server
|
|
240
|
+
"""
|
|
241
|
+
if name is not None and not isinstance(name, str):
|
|
242
|
+
raise Exception(f"Name must be a string, not {type(name)} !")
|
|
243
|
+
|
|
244
|
+
if not isinstance(position, (_MissingSentinel, int)):
|
|
245
|
+
raise Exception(f"Position must be an integer, not {type(position)} !")
|
|
246
|
+
|
|
247
|
+
if not isinstance(category, (_MissingSentinel, int)):
|
|
248
|
+
raise Exception(f"Category must be an integer, not {type(category)} !")
|
|
249
|
+
|
|
250
|
+
if not isinstance(slowmode, (_MissingSentinel, int)):
|
|
251
|
+
raise Exception(f"Slowmode must be an integer, not {type(slowmode)} !")
|
|
252
|
+
|
|
253
|
+
if not isinstance(topic, (_MissingSentinel, str)):
|
|
254
|
+
raise Exception(f"Topic must be a string, not {type(topic)} !")
|
|
255
|
+
|
|
256
|
+
if not isinstance(nsfw, (_MissingSentinel, bool)):
|
|
257
|
+
raise Exception(f"NSFW must be a boolean, not {type(nsfw)} !")
|
|
258
|
+
|
|
259
|
+
channel_to_edit = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
260
|
+
new_categoy = ctx.channel.category if isinstance(category, _MissingSentinel) else ctx.channel.guild.get_channel(category)
|
|
261
|
+
|
|
262
|
+
if channel_to_edit is None:
|
|
263
|
+
raise Exception(f"Channel {channel} not found !")
|
|
264
|
+
|
|
265
|
+
await channel_to_edit.edit(name=name if name is not None else channel_to_edit.name,
|
|
266
|
+
position=position if position is not MISSING else channel_to_edit.position,
|
|
267
|
+
category=new_categoy,
|
|
268
|
+
slowmode_delay=slowmode if slowmode is not MISSING else channel_to_edit.slowmode_delay,
|
|
269
|
+
topic=topic if topic is not MISSING else channel_to_edit.topic,
|
|
270
|
+
nsfw=nsfw if nsfw is not MISSING else channel_to_edit.nsfw,
|
|
271
|
+
overwrites=permissions if permissions is not MISSING else channel_to_edit.overwrites,
|
|
272
|
+
reason=reason)
|
|
273
|
+
|
|
274
|
+
return channel_to_edit.id
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
async def dshell_edit_voice_channel(ctx: Message,
|
|
278
|
+
channel=None,
|
|
279
|
+
name=None,
|
|
280
|
+
category=MISSING,
|
|
281
|
+
position=MISSING,
|
|
282
|
+
bitrate=MISSING,
|
|
283
|
+
permissions: dict[Union[Member, Role], PermissionOverwrite] = MISSING,
|
|
284
|
+
reason=None):
|
|
285
|
+
"""
|
|
286
|
+
Edits a voice channel on the server
|
|
287
|
+
"""
|
|
288
|
+
if not isinstance(position, (_MissingSentinel, int)):
|
|
289
|
+
raise Exception(f"Position must be an integer, not {type(position)} !")
|
|
290
|
+
|
|
291
|
+
if not isinstance(category, (_MissingSentinel, int)):
|
|
292
|
+
raise Exception(f"Category must be an integer, not {type(category)} !")
|
|
293
|
+
|
|
294
|
+
if not isinstance(bitrate, (_MissingSentinel, int)):
|
|
295
|
+
raise Exception(f"Bitrate must be an integer, not {type(bitrate)} !")
|
|
296
|
+
|
|
297
|
+
channel_to_edit = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
298
|
+
new_categoy = ctx.channel.category if isinstance(category, _MissingSentinel) else ctx.channel.guild.get_channel(category)
|
|
299
|
+
|
|
300
|
+
if channel_to_edit is None:
|
|
301
|
+
raise Exception(f"Channel {channel} not found !")
|
|
302
|
+
|
|
303
|
+
await channel_to_edit.edit(name=name if name is not None else channel_to_edit.name,
|
|
304
|
+
position=position if position is not MISSING else channel_to_edit.position,
|
|
305
|
+
category=new_categoy,
|
|
306
|
+
bitrate=bitrate if bitrate is not MISSING else channel_to_edit.bitrate,
|
|
307
|
+
overwrites=permissions if permissions is not MISSING else channel_to_edit.overwrites,
|
|
308
|
+
reason=reason)
|
|
309
|
+
|
|
310
|
+
return channel_to_edit.id
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
async def dshell_create_thread_message(ctx: Message,
|
|
314
|
+
name,
|
|
315
|
+
message: Union[int, str] = None,
|
|
316
|
+
archive=MISSING,
|
|
317
|
+
slowmode=MISSING):
|
|
318
|
+
"""
|
|
319
|
+
Creates a thread from a message.
|
|
320
|
+
"""
|
|
321
|
+
|
|
322
|
+
if message is None:
|
|
323
|
+
message = ctx.id
|
|
324
|
+
|
|
325
|
+
message = utils_get_message(ctx, message)
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
if not isinstance(name, str):
|
|
329
|
+
raise Exception(f"Name must be a string, not {type(name)} !")
|
|
330
|
+
|
|
331
|
+
if not isinstance(archive, (_MissingSentinel, int)):
|
|
332
|
+
raise Exception(f"Auto archive duration must be an integer, not {type(archive)} !")
|
|
333
|
+
|
|
334
|
+
if not isinstance(archive, _MissingSentinel) and archive not in (60, 1440, 4320, 10080):
|
|
335
|
+
raise Exception("Auto archive duration must be one of the following values: 60, 1440, 4320, 10080 !")
|
|
336
|
+
|
|
337
|
+
if not isinstance(slowmode, (_MissingSentinel, int)):
|
|
338
|
+
raise Exception(f"Slowmode delay must be an integer, not {type(slowmode)} !")
|
|
339
|
+
|
|
340
|
+
if not isinstance(slowmode, _MissingSentinel) and slowmode < 0:
|
|
341
|
+
raise Exception("Slowmode delay must be a positive integer !")
|
|
342
|
+
|
|
343
|
+
if isinstance(message, PartialMessage):
|
|
344
|
+
m = await message.fetch()
|
|
345
|
+
else:
|
|
346
|
+
m = message
|
|
347
|
+
|
|
348
|
+
thread = await m.create_thread(name=name,
|
|
349
|
+
auto_archive_duration=archive,
|
|
350
|
+
slowmode_delay=slowmode)
|
|
351
|
+
|
|
352
|
+
return thread.id
|
|
353
|
+
|
|
354
|
+
async def dshell_edit_thread(ctx: Message,
|
|
355
|
+
thread: Union[int, str] = None,
|
|
356
|
+
name=None,
|
|
357
|
+
archive=MISSING,
|
|
358
|
+
slowmode=MISSING,
|
|
359
|
+
reason=None):
|
|
360
|
+
""" Edits a thread.
|
|
361
|
+
"""
|
|
362
|
+
if thread is None:
|
|
363
|
+
thread = ctx.thread
|
|
364
|
+
|
|
365
|
+
if thread is None:
|
|
366
|
+
raise Exception("Thread must be specified !")
|
|
367
|
+
|
|
368
|
+
thread = await utils_get_thread(ctx, thread)
|
|
369
|
+
|
|
370
|
+
if not isinstance(name, (_MissingSentinel, str)):
|
|
371
|
+
raise Exception(f"Name must be a string, not {type(name)} !")
|
|
372
|
+
|
|
373
|
+
if not isinstance(archive, (_MissingSentinel, int)):
|
|
374
|
+
raise Exception(f"Auto archive duration must be an integer, not {type(archive)} !")
|
|
375
|
+
|
|
376
|
+
if not isinstance(archive, _MissingSentinel) and archive not in (60, 1440, 4320, 10080):
|
|
377
|
+
raise Exception("Auto archive duration must be one of the following values: 60, 1440, 4320, 10080 !")
|
|
378
|
+
|
|
379
|
+
if not isinstance(slowmode, (_MissingSentinel, int)):
|
|
380
|
+
raise Exception(f"Slowmode delay must be an integer, not {type(slowmode)} !")
|
|
381
|
+
|
|
382
|
+
if not isinstance(slowmode, _MissingSentinel) and slowmode < 0:
|
|
383
|
+
raise Exception("Slowmode delay must be a positive integer !")
|
|
384
|
+
|
|
385
|
+
await thread.edit(name=name if name is not None else thread.name,
|
|
386
|
+
auto_archive_duration=archive if archive is not MISSING else thread.auto_archive_duration,
|
|
387
|
+
slowmode_delay=slowmode if slowmode is not MISSING else thread.slowmode_delay,
|
|
388
|
+
reason=reason)
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
async def dshell_get_thread(ctx: Message, message: Union[int, str] = None):
|
|
392
|
+
"""
|
|
393
|
+
Returns the thread object of the specified thread ID.
|
|
394
|
+
"""
|
|
395
|
+
|
|
396
|
+
if message is None:
|
|
397
|
+
message = ctx.id
|
|
398
|
+
|
|
399
|
+
target_message = utils_get_message(ctx, message)
|
|
400
|
+
if isinstance(target_message, PartialMessage):
|
|
401
|
+
message = await target_message.fetch()
|
|
402
|
+
else:
|
|
403
|
+
message = target_message
|
|
404
|
+
|
|
405
|
+
if not hasattr(message, 'thread'):
|
|
406
|
+
return None
|
|
407
|
+
|
|
408
|
+
thread = message.thread
|
|
409
|
+
|
|
410
|
+
if thread is None:
|
|
411
|
+
return None
|
|
412
|
+
|
|
413
|
+
return thread.id
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
async def dshell_delete_thread(ctx: Message, thread: Union[int, str] = None, reason=None):
|
|
417
|
+
"""
|
|
418
|
+
Deletes a thread.
|
|
419
|
+
"""
|
|
420
|
+
|
|
421
|
+
if thread is None:
|
|
422
|
+
thread = ctx.id
|
|
423
|
+
|
|
424
|
+
target_message = utils_get_message(ctx, thread)
|
|
425
|
+
if isinstance(target_message, PartialMessage):
|
|
426
|
+
thread = await target_message.fetch()
|
|
427
|
+
else:
|
|
428
|
+
thread = target_message
|
|
429
|
+
|
|
430
|
+
if not hasattr(thread, 'thread'):
|
|
431
|
+
raise Exception("The specified message does not have a thread !")
|
|
432
|
+
|
|
433
|
+
if thread.thread is None:
|
|
434
|
+
raise Exception("The specified message does not have a thread !")
|
|
435
|
+
|
|
436
|
+
await thread.thread.delete(reason=reason)
|
|
437
|
+
|
|
438
|
+
return thread.thread.id
|
|
439
|
+
|
|
440
|
+
async def dshell_create_category(ctx: Message,
|
|
441
|
+
name,
|
|
442
|
+
position=MISSING,
|
|
443
|
+
permissions: dict[Union[Member, Role], PermissionOverwrite] = MISSING,
|
|
444
|
+
reason=None):
|
|
445
|
+
"""
|
|
446
|
+
Creates a category on the server
|
|
447
|
+
"""
|
|
448
|
+
|
|
449
|
+
if not isinstance(position, (_MissingSentinel, int)):
|
|
450
|
+
raise Exception(f"Position must be an integer, not {type(position)} !")
|
|
451
|
+
|
|
452
|
+
created_category = await ctx.guild.create_category(str(name),
|
|
453
|
+
position=position,
|
|
454
|
+
overwrites=permissions,
|
|
455
|
+
reason=reason)
|
|
456
|
+
|
|
457
|
+
return created_category.id
|
|
458
|
+
|
|
459
|
+
async def dshell_edit_category(ctx: Message,
|
|
460
|
+
category,
|
|
461
|
+
name=None,
|
|
462
|
+
position=MISSING,
|
|
463
|
+
permissions: dict[Union[Member, Role], PermissionOverwrite] = MISSING,
|
|
464
|
+
reason=None):
|
|
465
|
+
"""
|
|
466
|
+
Edits a category on the server
|
|
467
|
+
"""
|
|
468
|
+
if not isinstance(position, (_MissingSentinel, int)):
|
|
469
|
+
raise Exception(f"Position must be an integer, not {type(position)} !")
|
|
470
|
+
|
|
471
|
+
category_to_edit = ctx.channel.guild.get_channel(category)
|
|
472
|
+
|
|
473
|
+
if category_to_edit is None or not isinstance(category_to_edit, CategoryChannel):
|
|
474
|
+
raise Exception(f"Category {category} not found or is not a category !")
|
|
475
|
+
|
|
476
|
+
await category_to_edit.edit(name=name if name is not None else category_to_edit.name,
|
|
477
|
+
position=position if position is not MISSING else category_to_edit.position,
|
|
478
|
+
overwrites=permissions if permissions is not MISSING else category_to_edit.overwrites,
|
|
479
|
+
reason=reason)
|
|
480
|
+
|
|
481
|
+
return category_to_edit.id
|
|
482
|
+
|
|
483
|
+
async def dshell_delete_category(ctx: Message, category=None, reason=None):
|
|
484
|
+
"""
|
|
485
|
+
Deletes a category.
|
|
486
|
+
"""
|
|
487
|
+
|
|
488
|
+
if category is None and ctx.channel.category is None:
|
|
489
|
+
raise Exception("Category must be specified !")
|
|
490
|
+
|
|
491
|
+
category_to_delete = ctx.channel.category if category is None else ctx.channel.guild.get_channel(category)
|
|
492
|
+
|
|
493
|
+
if category_to_delete is None or not isinstance(category_to_delete, CategoryChannel):
|
|
494
|
+
raise Exception(f"Category {category} not found or is not a category !")
|
|
495
|
+
|
|
496
|
+
await category_to_delete.delete(reason=reason)
|
|
497
|
+
|
|
498
|
+
return category_to_delete.id
|
|
499
|
+
|
|
500
|
+
############################# CHANNEL INFO ##############################
|
|
501
|
+
|
|
502
|
+
async def dshell_get_channel_category_id(ctx: Message, channel=None):
|
|
503
|
+
"""
|
|
504
|
+
Returns the category ID of a channel.
|
|
505
|
+
"""
|
|
506
|
+
|
|
507
|
+
channel_to_check = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
508
|
+
|
|
509
|
+
if channel_to_check is None:
|
|
510
|
+
raise Exception(f"Channel {channel} not found !")
|
|
511
|
+
|
|
512
|
+
if channel_to_check.category is None:
|
|
513
|
+
return None
|
|
514
|
+
|
|
515
|
+
return channel_to_check.category.id if channel_to_check.category is not None else 0
|
|
516
|
+
|
|
517
|
+
async def dshell_get_channel_nsfw(ctx: Message, channel=None):
|
|
518
|
+
"""
|
|
519
|
+
Returns if the channel is NSFW.
|
|
520
|
+
"""
|
|
521
|
+
|
|
522
|
+
channel_to_check = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
523
|
+
|
|
524
|
+
if channel_to_check is None:
|
|
525
|
+
raise Exception(f"Channel {channel} not found !")
|
|
526
|
+
|
|
527
|
+
return channel_to_check.nsfw
|
|
528
|
+
|
|
529
|
+
async def dshell_get_channel_slowmode(ctx: Message, channel=None):
|
|
530
|
+
"""
|
|
531
|
+
Returns the slowmode delay of a channel.
|
|
532
|
+
"""
|
|
533
|
+
|
|
534
|
+
channel_to_check = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
535
|
+
|
|
536
|
+
if channel_to_check is None:
|
|
537
|
+
raise Exception(f"Channel {channel} not found !")
|
|
538
|
+
|
|
539
|
+
if not hasattr(channel_to_check, 'slowmode_delay'):
|
|
540
|
+
raise Exception(f"Channel {channel} is not a text channel !")
|
|
541
|
+
|
|
542
|
+
return channel_to_check.slowmode_delay
|
|
543
|
+
|
|
544
|
+
async def dshell_get_channel_topic(ctx: Message, channel=None):
|
|
545
|
+
"""
|
|
546
|
+
Returns the topic of a channel.
|
|
547
|
+
"""
|
|
548
|
+
|
|
549
|
+
channel_to_check = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
550
|
+
|
|
551
|
+
if channel_to_check is None:
|
|
552
|
+
raise Exception(f"Channel {channel} not found !")
|
|
553
|
+
|
|
554
|
+
if not hasattr(channel_to_check, 'topic'):
|
|
555
|
+
raise Exception(f"Channel {channel} is not a text channel !")
|
|
556
|
+
|
|
557
|
+
return channel_to_check.topic
|
|
558
|
+
|
|
559
|
+
async def dshell_get_channel_threads(ctx: Message, channel=None):
|
|
560
|
+
"""
|
|
561
|
+
Returns the list of threads in a channel.
|
|
562
|
+
"""
|
|
563
|
+
|
|
564
|
+
channel_to_check = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
565
|
+
|
|
566
|
+
if channel_to_check is None:
|
|
567
|
+
raise Exception(f"Channel {channel} not found !")
|
|
568
|
+
|
|
569
|
+
if not hasattr(channel_to_check, 'threads'):
|
|
570
|
+
raise Exception(f"Channel {channel} is not a text channel !")
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
threads = ListNode([])
|
|
574
|
+
|
|
575
|
+
for thread in channel_to_check.threads:
|
|
576
|
+
threads.add(thread.id)
|
|
577
|
+
|
|
578
|
+
return threads
|
|
579
|
+
|
|
580
|
+
async def dshell_get_channel_position(ctx: Message, channel=None):
|
|
581
|
+
"""
|
|
582
|
+
Returns the position of a channel.
|
|
583
|
+
"""
|
|
584
|
+
|
|
585
|
+
channel_to_check = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
586
|
+
|
|
587
|
+
if channel_to_check is None:
|
|
588
|
+
raise Exception(f"Channel {channel} not found !")
|
|
589
|
+
|
|
590
|
+
return channel_to_check.position
|
|
591
|
+
|
|
592
|
+
async def dshell_get_channel_url(ctx: Message, channel=None):
|
|
593
|
+
"""
|
|
594
|
+
Returns the URL of a channel.
|
|
595
|
+
"""
|
|
596
|
+
|
|
597
|
+
channel_to_check = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
598
|
+
|
|
599
|
+
if channel_to_check is None:
|
|
600
|
+
raise Exception(f"Channel {channel} not found !")
|
|
601
|
+
|
|
602
|
+
return channel_to_check.jump_url
|
|
603
|
+
|
|
604
|
+
async def dshell_get_channel_voice_members(ctx: Message, channel=None):
|
|
605
|
+
"""
|
|
606
|
+
Returns the list of members in a voice channel.
|
|
607
|
+
"""
|
|
608
|
+
|
|
609
|
+
channel_to_check = ctx.channel if channel is None else ctx.channel.guild.get_channel(channel)
|
|
610
|
+
|
|
611
|
+
if channel_to_check is None:
|
|
612
|
+
raise Exception(f"Channel {channel} not found !")
|
|
613
|
+
|
|
614
|
+
if not isinstance(channel_to_check, VoiceChannel):
|
|
615
|
+
raise Exception(f"Channel {channel} is not a voice channel !")
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
members = ListNode([])
|
|
619
|
+
|
|
620
|
+
for member in channel_to_check.members:
|
|
621
|
+
members.add(member.id)
|
|
622
|
+
|
|
623
|
+
return members
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from .._DshellTokenizer.dshell_token_type import Token
|
|
2
|
+
|
|
3
|
+
from .._DshellParser.ast_nodes import FieldEmbedNode
|
|
4
|
+
|
|
5
|
+
from .._DshellInterpreteur.utils_interpreter import regroupe_commandes
|
|
6
|
+
|
|
7
|
+
from Dshell.full_import import Embed
|
|
8
|
+
|
|
9
|
+
from Dshell.full_import import Any, TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
from .utils.utils_global import utils_build_colour
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from .._DshellInterpreteur.dshell_interpreter import DshellInterpreteur
|
|
15
|
+
|
|
16
|
+
async def build_embed_args(body: list[Token], fields: list[FieldEmbedNode], interpreter: "DshellInterpreteur") -> tuple[dict, list[dict]]:
|
|
17
|
+
"""
|
|
18
|
+
Builds the arguments for an embed from the command information.
|
|
19
|
+
"""
|
|
20
|
+
regrouped_parameters = await regroupe_commandes(body, interpreter)
|
|
21
|
+
args_main_embed: dict[str, list[Any]] = regrouped_parameters.get_dict_parameters()
|
|
22
|
+
args_main_embed.pop('*') # remove unspecified parameters for the embed
|
|
23
|
+
args_main_embed: dict[str, Token] # specify what it contains from now on
|
|
24
|
+
|
|
25
|
+
args_fields: list[dict[str, Token]] = []
|
|
26
|
+
for field in fields: # do the same for the fields
|
|
27
|
+
y = await regroupe_commandes(field.body, interpreter)
|
|
28
|
+
args_field = y.get_dict_parameters()
|
|
29
|
+
args_field.pop('*')
|
|
30
|
+
args_field: dict[str, Token]
|
|
31
|
+
args_fields.append(args_field)
|
|
32
|
+
|
|
33
|
+
if 'color' in args_main_embed:
|
|
34
|
+
args_main_embed['color'] = utils_build_colour(args_main_embed['color']) # convert color to Colour object or int
|
|
35
|
+
|
|
36
|
+
return args_main_embed, args_fields
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
async def build_embed(body: list[Token], fields: list[FieldEmbedNode], interpreter: "DshellInterpreteur") -> Embed:
|
|
40
|
+
"""
|
|
41
|
+
Builds an embed from the command information.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
args_main_embed, args_fields = await build_embed_args(body, fields, interpreter)
|
|
45
|
+
embed = Embed(**args_main_embed) # build the main embed
|
|
46
|
+
for field in args_fields:
|
|
47
|
+
embed.add_field(**field) # add all fields
|
|
48
|
+
|
|
49
|
+
return embed
|
|
50
|
+
|
|
51
|
+
async def rebuild_embed(embed: Embed, body: list[Token], fields: list[FieldEmbedNode], interpreter: "DshellInterpreteur") -> Embed:
|
|
52
|
+
"""
|
|
53
|
+
Rebuilds an embed from an existing embed and the command information.
|
|
54
|
+
"""
|
|
55
|
+
args_main_embed, args_fields = await build_embed_args(body, fields, interpreter)
|
|
56
|
+
|
|
57
|
+
for key, value in args_main_embed.items():
|
|
58
|
+
if key == 'color':
|
|
59
|
+
embed.colour = value
|
|
60
|
+
else:
|
|
61
|
+
setattr(embed, key, value)
|
|
62
|
+
|
|
63
|
+
if args_fields:
|
|
64
|
+
embed.clear_fields()
|
|
65
|
+
for field in args_fields:
|
|
66
|
+
embed.add_field(**field)
|
|
67
|
+
|
|
68
|
+
return embed
|