dshellInterpreter 0.1.4__py3-none-any.whl → 0.1.6__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.

@@ -1,7 +1,8 @@
1
1
  from asyncio import sleep
2
2
  from re import search
3
+ from typing import Union
3
4
 
4
- from discord import MISSING
5
+ from discord import MISSING, PermissionOverwrite, Member, Role
5
6
  from discord.abc import GuildChannel
6
7
 
7
8
  __all__ = [
@@ -10,8 +11,10 @@ __all__ = [
10
11
  'dshell_delete_channels'
11
12
  ]
12
13
 
14
+
13
15
  async def dshell_create_text_channel(ctx: GuildChannel, name, category=None, position=MISSING, slowmode=MISSING,
14
- topic=MISSING, nsfw=MISSING):
16
+ topic=MISSING, nsfw=MISSING,
17
+ permission: dict[Union[Member, Role], PermissionOverwrite] = MISSING):
15
18
  """
16
19
  Crée un salon textuel sur le serveur
17
20
  """
@@ -23,7 +26,8 @@ async def dshell_create_text_channel(ctx: GuildChannel, name, category=None, pos
23
26
  position=position,
24
27
  slowmode_delay=slowmode,
25
28
  topic=topic,
26
- nsfw=nsfw)
29
+ nsfw=nsfw,
30
+ overwrites=permission._values)
27
31
 
28
32
  return created_channel.id
29
33
 
@@ -1,7 +1,6 @@
1
1
  from discord import Embed
2
2
  from discord.abc import GuildChannel
3
3
 
4
- from .._DshellParser.ast_nodes import ListNode
5
4
 
6
5
  __all__ = [
7
6
  'dshell_send_message',
@@ -9,8 +8,9 @@ __all__ = [
9
8
  'dshell_purge_message'
10
9
  ]
11
10
 
12
- async def dshell_send_message(ctx: GuildChannel, message=None, delete=None, channel=None, embeds: ListNode = None,
13
- embed=None):
11
+
12
+ async def dshell_send_message(ctx: GuildChannel, message=None, delete=None, channel=None, embeds=None, embed=None):
13
+ from .._DshellParser.ast_nodes import ListNode
14
14
  """
15
15
  Envoie un message sur Discord
16
16
  """
@@ -2,13 +2,13 @@ from asyncio import sleep
2
2
  from re import findall
3
3
  from typing import TypeVar, Union, Any, Optional, Callable
4
4
 
5
- from discord import AutoShardedBot, Embed, Colour, PermissionOverwrite, Permissions
5
+ from discord import AutoShardedBot, Embed, Colour, PermissionOverwrite, Permissions, Guild, Member, Role
6
6
  from discord.abc import GuildChannel, PrivateChannel
7
7
 
8
- from .._DshellTokenizer.dshell_keywords import *
9
8
  from .._DshellParser.ast_nodes import *
10
9
  from .._DshellParser.dshell_parser import parse
11
10
  from .._DshellParser.dshell_parser import to_postfix, print_ast
11
+ from .._DshellTokenizer.dshell_keywords import *
12
12
  from .._DshellTokenizer.dshell_token_type import DshellTokenType as DTT
13
13
  from .._DshellTokenizer.dshell_token_type import Token
14
14
  from .._DshellTokenizer.dshell_tokenizer import DshellTokenizer
@@ -182,7 +182,7 @@ async def call_function(function: Callable, args: ArgsCommandNode, interpreter:
182
182
  """
183
183
  Appelle une fonction avec évaluation des arguments Dshell en valeurs Python
184
184
  """
185
- reformatted = regroupe_commandes(args.body, interpreter)
185
+ reformatted = regroupe_commandes(args.body, interpreter)[0]
186
186
 
187
187
  # conversion des args en valeurs Python
188
188
  absolute_args = reformatted.pop('*', list())
@@ -196,7 +196,7 @@ async def call_function(function: Callable, args: ArgsCommandNode, interpreter:
196
196
  return await function(*absolute_args, **keyword_args)
197
197
 
198
198
 
199
- def regroupe_commandes(body: list[Token], interpreter: DshellInterpreteur) -> dict[Union[str, Token], list[Any]]:
199
+ def regroupe_commandes(body: list[Token], interpreter: DshellInterpreteur) -> list[dict[str, list[Any]]]:
200
200
  """
201
201
  Regroupe les arguments de la commande sous la forme d'un dictionnaire python.
202
202
  Sachant que l'on peut spécifier le paramètre que l'on souhaite passer via -- suivit du nom du paramètre. Mais ce n'est pas obligatoire !
@@ -206,6 +206,7 @@ def regroupe_commandes(body: list[Token], interpreter: DshellInterpreteur) -> di
206
206
  tokens = {'*': []} # les tokens à renvoyer
207
207
  current_arg = '*' # les clés des arguments sont les types auquels ils appartiennent. L'* sert à tous les arguments non explicité par un séparateur et un IDENT
208
208
  n = len(body)
209
+ list_tokens: list[dict] = [tokens]
209
210
 
210
211
  i = 0
211
212
  while i < n:
@@ -214,26 +215,36 @@ def regroupe_commandes(body: list[Token], interpreter: DshellInterpreteur) -> di
214
215
  current_arg = body[i + 1].value # on change l'argument actuel. Il sera donc impossible de revenir à l'*
215
216
  tokens[current_arg] = '' # on lui crée une paire clé/valeur
216
217
  i += 2 # on skip l'IDENT qu'il y a après le séparateur car on vient de le traiter
218
+
219
+ elif body[
220
+ i].type == DTT.SUB_SEPARATOR: # permet de délimiter les paramètres et de pouvoir en mettre plusieurs ayant le même nom
221
+ list_tokens += regroupe_commandes(
222
+ [Token(
223
+ type_=DTT.SEPARATOR, value=body[i].value, position=body[i].position)
224
+ ] + body[i + 1:], interpreter
225
+ ) # on ajoute un sous-dictionnaire pour les sous-commandes
226
+ return list_tokens
227
+
217
228
  else:
218
229
  if current_arg == '*':
219
230
  tokens[current_arg].append(interpreter.eval_data_token(body[i]))
220
231
  else:
221
232
  tokens[current_arg] = interpreter.eval_data_token(body[i]) # on ajoute le token à l'argument actuel
222
233
  i += 1
223
- return tokens
234
+ return list_tokens
224
235
 
225
236
 
226
237
  def build_embed(body: list[Token], fields: list[FieldEmbedNode], interpreter: DshellInterpreteur) -> Embed:
227
238
  """
228
239
  Construit un embed à partir des informations de la commande.
229
240
  """
230
- args_main_embed: dict[Union[str, Token], list[Any]] = regroupe_commandes(body, interpreter)
241
+ args_main_embed: dict[str, list[Any]] = regroupe_commandes(body, interpreter)[0]
231
242
  args_main_embed.pop('*') # on enlève les paramètres non spécifié pour l'embed
232
243
  args_main_embed: dict[str, Token] # on précise se qu'il contient dorénavant
233
244
 
234
245
  args_fields: list[dict[str, Token]] = []
235
246
  for field in fields: # on fait la même chose pour tous les fields
236
- a = regroupe_commandes(field.body, interpreter)
247
+ a = regroupe_commandes(field.body, interpreter)[0]
237
248
  a.pop('*')
238
249
  a: dict[str, Token]
239
250
  args_fields.append(a)
@@ -248,28 +259,20 @@ def build_embed(body: list[Token], fields: list[FieldEmbedNode], interpreter: Ds
248
259
 
249
260
  return embed
250
261
 
251
- def build_permission(body: list[Token], interpreter: DshellInterpreteur) -> PermissionOverwrite:
262
+
263
+ def build_permission(body: list[Token], interpreter: DshellInterpreteur) -> dict[
264
+ Union[Member, Role], PermissionOverwrite]:
252
265
  """
253
266
  Construit un dictionnaire de permissions à partir des informations de la commande.
254
267
  """
255
- args_permissions: dict[Union[str, Token], list[Any]] = regroupe_commandes(body, interpreter)
256
- args_permissions.pop('*') # on enlève les paramètres non spécifié pour les permissions
257
- args_permissions: dict[str, Token] # on précise se qu'il contient dorénavant
258
-
259
- permissions = PermissionOverwrite()
260
-
261
- for key, value in args_permissions.items():
262
-
263
- if key == 'allowed':
264
- permissions.update(**PermissionOverwrite.from_pair(Permissions(value), Permissions())._values)
265
-
266
- elif key == 'denied':
267
- permissions.update(**PermissionOverwrite.from_pair(Permissions(), Permissions(value))._values)
268
+ args_permissions: list[dict[str, list[Any]]] = regroupe_commandes(body, interpreter)
269
+ permissions: dict[Union[Member, Role], PermissionOverwrite] = {}
268
270
 
269
- else:
270
- permissions.update(**{key: value})
271
+ for i in args_permissions:
272
+ i.pop('*')
273
+ permissions.update(DshellPermissions(i).get_permission_overwrite(interpreter.ctx.guild))
271
274
 
272
- return permissions
275
+ print(args_permissions)
273
276
 
274
277
 
275
278
  class DshellIterator:
@@ -296,3 +299,98 @@ class DshellIterator:
296
299
  value = self.data[self.current]
297
300
  self.current += 1
298
301
  return value
302
+
303
+
304
+ class DshellPermissions:
305
+
306
+ def __init__(self, target: dict[str, list[int]]):
307
+ """
308
+ Permet de créer un objet de permissions Dshell.
309
+ :param target: Un dictionnaire contenant les paramètres et leurs valeurs.
310
+ Paramètres attendus : "allow", "deny", "members", "roles".
311
+ Pour "members" et "roles", les valeurs doivent être des ListNode d'IDs.
312
+ """
313
+ self.target: dict[str, Union[ListNode, int]] = target
314
+
315
+ @staticmethod
316
+ def get_instance(guild: Guild, target_id: int) -> Union[Member, Role]:
317
+ """
318
+ Retourne l'instance correspondante à l'id donné. Uniquement un Member ou un Role.
319
+ :param guild: Le serveur Discord dans lequel chercher
320
+ :param target_id: L'ID du membre ou du rôle
321
+ :return: Une instance de Member ou Role
322
+ """
323
+ try:
324
+ member = DshellPermissions.get_member(guild, target_id)
325
+ except ValueError:
326
+ member = None
327
+
328
+ try:
329
+ role = DshellPermissions.get_role(guild, target_id)
330
+ except ValueError:
331
+ role = None
332
+
333
+ if member is not None:
334
+ return member
335
+
336
+ if role is not None:
337
+ return role
338
+
339
+ raise ValueError(f"Aucun membre ou rôle trouvé avec l'ID {target_id} dans le serveur {guild.name}.")
340
+
341
+ @staticmethod
342
+ def get_member(guild: Guild, target_id: int) -> Member:
343
+ """
344
+ Retourne l'instance de Member correspondante à l'id donné.
345
+ :param guild: Le serveur Discord dans lequel chercher
346
+ :param target_id: L'ID du membre
347
+ :return: Une instance de Member
348
+ """
349
+ member = guild.get_member(target_id)
350
+ if member is not None:
351
+ return member
352
+
353
+ raise ValueError(f"Aucun membre trouvé avec l'ID {target_id} dans le serveur {guild.name}.")
354
+
355
+ @staticmethod
356
+ def get_role(guild: Guild, target_id: int) -> Role:
357
+ """
358
+ Retourne l'instance de Role correspondante à l'id donné.
359
+ :param guild: Le serveur Discord dans lequel chercher
360
+ :param target_id: L'ID du rôle
361
+ :return: Une instance de Role
362
+ """
363
+ role = guild.get_role(target_id)
364
+ if role is not None:
365
+ return role
366
+
367
+ raise ValueError(f"Aucun rôle trouvé avec l'ID {target_id} dans le serveur {guild.name}.")
368
+
369
+ def get_permission_overwrite(self, guild: Guild) -> dict[Union[Member, Role], PermissionOverwrite]:
370
+ """
371
+ Retourne un objet PermissionOverwrite avec les permissions des membres et rôles.
372
+ :param guild: Le serveur Discord
373
+ :return: Un objet PermissionOverwrite
374
+ """
375
+ permissions: dict[Union[Member, Role], PermissionOverwrite] = {}
376
+ target_keys = self.target.keys()
377
+
378
+ if 'members' in target_keys:
379
+ for member_id in self.target['members']:
380
+ member = self.get_member(guild, member_id)
381
+ permissions[member] = PermissionOverwrite.from_pair(
382
+ allow=Permissions(permissions=self.target.get('allow', 0)),
383
+ deny= Permissions(permissions=self.target.get('deny', 0))
384
+ )
385
+
386
+ elif 'roles' in target_keys:
387
+ for role_id in self.target['roles']:
388
+ role = self.get_role(guild, role_id)
389
+ permissions[role] = PermissionOverwrite.from_pair(
390
+ allow=Permissions(permissions=self.target.get('allow', 0)),
391
+ deny= Permissions(permissions=self.target.get('deny', 0))
392
+ )
393
+ else:
394
+ raise ValueError("Aucun membre ou rôle spécifié dans les permissions.")
395
+
396
+ return permissions
@@ -1,7 +1,8 @@
1
- from typing import Optional, Any
1
+ from typing import Optional, Any, TYPE_CHECKING
2
2
 
3
3
  from .._DshellTokenizer.dshell_token_type import Token
4
4
 
5
+
5
6
  __all__ = [
6
7
  'ASTNode',
7
8
  'StartNode',
@@ -21,6 +22,7 @@ __all__ = [
21
22
  'PermissionNode'
22
23
  ]
23
24
 
25
+
24
26
  class ASTNode:
25
27
  pass
26
28
 
@@ -122,6 +124,7 @@ class EmbedNode(ASTNode):
122
124
  def __repr__(self):
123
125
  return f"<EMBED> - {self.body}"
124
126
 
127
+
125
128
  class PermissionNode(ASTNode):
126
129
  def __init__(self, body: list[Token]):
127
130
  self.body = body
@@ -6,7 +6,9 @@ __all__ = [
6
6
  "dshell_logical_operators",
7
7
  "dshell_operators"
8
8
  ]
9
+
9
10
  from typing import Callable
11
+
10
12
  from ..DISCORD_COMMANDS.dshell_channel import *
11
13
  from ..DISCORD_COMMANDS.dshell_message import *
12
14
 
@@ -14,7 +16,6 @@ dshell_keyword: set[str] = {
14
16
  'if', 'else', 'elif', 'loop', '#end', 'var', '#loop', '#if', 'sleep'
15
17
  }
16
18
 
17
-
18
19
  dshell_discord_keyword: set[str] = {
19
20
  'embed', '#embed', 'field', 'perm', 'permission', '#perm', '#permission'
20
21
  }
@@ -68,8 +69,6 @@ dshell_logical_operators: dict[str, tuple[Callable, int]] = {
68
69
  dshell_operators: dict[str, tuple[Callable, int]] = dshell_logical_operators.copy()
69
70
  dshell_operators.update(dshell_mathematical_operators)
70
71
 
71
-
72
-
73
72
  '''
74
73
  C_create_var = "var"
75
74
  C_obligate_var = "ovar" # rend obligatoire les variables
@@ -24,7 +24,8 @@ class DshellTokenType(Enum):
24
24
  KEYWORD = auto() # if, let, end, etc.
25
25
  DISCORD_KEYWORD = auto() # embed, #embed...
26
26
  COMMAND = auto()
27
- SEPARATOR = auto()
27
+ SEPARATOR = auto() # --
28
+ SUB_SEPARATOR = auto(), # ~~
28
29
  MATHS_OPERATOR = auto() # ==, +, -, *, etc.
29
30
  LOGIC_OPERATOR = auto(),
30
31
  COMMENT = auto() # lignes commençant par ##
@@ -23,6 +23,7 @@ table_regex: dict[DTT, Pattern] = {
23
23
  DTT.KEYWORD: compile(rf"(?<!\w)(#?{'|'.join(dshell_keyword)})(?!\w)"),
24
24
  DTT.DISCORD_KEYWORD: compile(rf"(?<!\w|-)(#?{'|'.join(dshell_discord_keyword)})(?!\w|-)"),
25
25
  DTT.SEPARATOR: compile(rf"(--)"),
26
+ DTT.SUB_SEPARATOR: compile(rf"(~~)"),
26
27
  DTT.COMMAND: compile(rf"\b({'|'.join(dshell_commands.keys())})\b"),
27
28
  DTT.MATHS_OPERATOR: compile(rf"({'|'.join([escape(i) for i in dshell_mathematical_operators.keys()])})"),
28
29
  DTT.LOGIC_OPERATOR: compile(rf"(?<!\w)({'|'.join([escape(i) for i in dshell_logical_operators.keys()])})(?<!\w)"),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dshellInterpreter
3
- Version: 0.1.4
3
+ Version: 0.1.6
4
4
  Summary: A Discord bot interpreter for creating custom commands and automations.
5
5
  Home-page: https://github.com/BOXERRMD/Dshell_Interpreter
6
6
  Author: Chronos
@@ -31,4 +31,5 @@ Dynamic: requires-python
31
31
  Dynamic: summary
32
32
 
33
33
  # Dshell_Interpreter
34
+
34
35
  Python interpreter for Discord.
@@ -0,0 +1,18 @@
1
+ Dshell/__init__.py,sha256=UPvXnewe_8FX9aoevMA78UN1k8AY-u8LTY3vEVxaDxw,72
2
+ Dshell/DISCORD_COMMANDS/__init__.py,sha256=s58iMazDXNPDLZ3Hvymh__C5w7lcgEvaYfX0-SHocRo,62
3
+ Dshell/DISCORD_COMMANDS/dshell_channel.py,sha256=Vtmp9J-h89cxL46enLWG1GNN7s1jNQgd-ZRvponq49I,2396
4
+ Dshell/DISCORD_COMMANDS/dshell_message.py,sha256=FhUo_zpdHJErsAjKyO34SXPdDkwPmE_QSli5svIpI4E,1882
5
+ Dshell/_DshellInterpreteur/__init__.py,sha256=xy5-J-R3YmY99JF3NBHTRRLsComFxpjnCA5xacISctU,35
6
+ Dshell/_DshellInterpreteur/dshell_interpreter.py,sha256=6EzLmV7s8xT0tpg31ZyPieLpNqzB23plPJDcWPwYqv8,15942
7
+ Dshell/_DshellParser/__init__.py,sha256=ONDfhZMvClqP_6tE8SLjp-cf3pXL-auQYnfYRrHZxC4,56
8
+ Dshell/_DshellParser/ast_nodes.py,sha256=3QyfTGCNeCn2e1QFda1DMiGziLPgGNMnRh5_XyzR8BI,5704
9
+ Dshell/_DshellParser/dshell_parser.py,sha256=mA8uA-xBhKcfnSKfLfePwI_fD0GrHbj0VBVeJPbcGas,13956
10
+ Dshell/_DshellTokenizer/__init__.py,sha256=LIQSRhDx2B9pmPx5ADMwwD0Xr9ybneVLhHH8qrJWw_s,172
11
+ Dshell/_DshellTokenizer/dshell_keywords.py,sha256=wTV89px9bUY4uf0KCnDr356H_dBIVgcPr55L_6-AWdg,3661
12
+ Dshell/_DshellTokenizer/dshell_token_type.py,sha256=NE-sVloBYtioZpWKnWuO5p0YcObGJZPNaKwc8lWDonQ,999
13
+ Dshell/_DshellTokenizer/dshell_tokenizer.py,sha256=2tto_gXYj94fLFx99p6nBbtplALT3Ysz9oBwatX9tIA,5788
14
+ dshellinterpreter-0.1.6.dist-info/licenses/LICENSE,sha256=lNgcw1_xb7QENAQi3uHGymaFtbs0RV-ihiCd7AoLQjA,1082
15
+ dshellinterpreter-0.1.6.dist-info/METADATA,sha256=x2myoZGTHcsxK6YTTnUTbUMPyVmQSQlX_DR3nT135Hg,1095
16
+ dshellinterpreter-0.1.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
+ dshellinterpreter-0.1.6.dist-info/top_level.txt,sha256=B4CMhtmchGwPQJLuqUy0GhRG-0cUGxKL4GqEbCiB_vE,7
18
+ dshellinterpreter-0.1.6.dist-info/RECORD,,
@@ -1,18 +0,0 @@
1
- Dshell/__init__.py,sha256=UPvXnewe_8FX9aoevMA78UN1k8AY-u8LTY3vEVxaDxw,72
2
- Dshell/DISCORD_COMMANDS/__init__.py,sha256=s58iMazDXNPDLZ3Hvymh__C5w7lcgEvaYfX0-SHocRo,62
3
- Dshell/DISCORD_COMMANDS/dshell_channel.py,sha256=IubzNzBtGEcbgkL_NJOWRY1oqE3Yb-ySDMUmoHKjGzM,2135
4
- Dshell/DISCORD_COMMANDS/dshell_message.py,sha256=jgSGBeDDHVy8u9fX2WN6wzh7I9WqVkeySlpmbJsBZjs,1919
5
- Dshell/_DshellInterpreteur/__init__.py,sha256=xy5-J-R3YmY99JF3NBHTRRLsComFxpjnCA5xacISctU,35
6
- Dshell/_DshellInterpreteur/dshell_interpreter.py,sha256=PvEmcUbXAsMP6mtmTgVJzDsnh3LwEAUQjkDQgJe4HLo,12023
7
- Dshell/_DshellParser/__init__.py,sha256=ONDfhZMvClqP_6tE8SLjp-cf3pXL-auQYnfYRrHZxC4,56
8
- Dshell/_DshellParser/ast_nodes.py,sha256=tAoLhxR0koG4iqWx0x9TvgHqamz5VHYisDjpAxnbJVE,5683
9
- Dshell/_DshellParser/dshell_parser.py,sha256=mA8uA-xBhKcfnSKfLfePwI_fD0GrHbj0VBVeJPbcGas,13956
10
- Dshell/_DshellTokenizer/__init__.py,sha256=LIQSRhDx2B9pmPx5ADMwwD0Xr9ybneVLhHH8qrJWw_s,172
11
- Dshell/_DshellTokenizer/dshell_keywords.py,sha256=KR9xVtinuisGe59juHcBngbKOG5jH0f1MFTTd-CBCQA,3663
12
- Dshell/_DshellTokenizer/dshell_token_type.py,sha256=EG-0I3mq4XznW75JVowOmlrWS3-WsBJPFcE6pjqrXwM,958
13
- Dshell/_DshellTokenizer/dshell_tokenizer.py,sha256=T-AKxnpFbJa-3rtknZEuNrPyGvCTfFXQeU2GsJqHzt8,5745
14
- dshellinterpreter-0.1.4.dist-info/licenses/LICENSE,sha256=lNgcw1_xb7QENAQi3uHGymaFtbs0RV-ihiCd7AoLQjA,1082
15
- dshellinterpreter-0.1.4.dist-info/METADATA,sha256=nH-VEca_4tFl-8Ysy0i5lmw9UiM4FBtccuxdruK0c2g,1093
16
- dshellinterpreter-0.1.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
- dshellinterpreter-0.1.4.dist-info/top_level.txt,sha256=B4CMhtmchGwPQJLuqUy0GhRG-0cUGxKL4GqEbCiB_vE,7
18
- dshellinterpreter-0.1.4.dist-info/RECORD,,