66import json
77import logging
88import pathlib
9- from typing import Any , Dict , Iterator , MutableMapping , Optional
9+ import re
10+ from typing import Any , Dict , Iterator , List , MutableMapping , Optional , Pattern , Tuple , Type
1011
1112import discord
1213import libwampli
1314from autobahn import wamp
1415from discord .ext import commands
1516
16- __all__ = ["WampliusCog" ,
17- "get_conn_id" ]
17+ __all__ = ["WampliusCog" ]
1818
1919log = logging .getLogger (__name__ )
2020
@@ -229,8 +229,6 @@ async def connect_cmd(self, ctx: commands.Context, url: str = None, realm: str =
229229 self ._switch_connection (get_conn_id (ctx ), connection )
230230
231231 embed = discord .Embed (title = "Joined session" , colour = discord .Colour .green ())
232- embed .add_field (name = "realm" , value = realm )
233-
234232 await ctx .send (embed = embed )
235233
236234 @commands .command ("disconnect" )
@@ -245,10 +243,43 @@ async def disconnect_cmd(self, ctx: commands.Context) -> None:
245243 embed = discord .Embed (title = "disconnected" , colour = discord .Colour .green ())
246244 await ctx .send (embed = embed )
247245
246+ async def substitute_variable (self , ctx : commands .Context , arg : str ) -> str :
247+ match = RE_SNOWFLAKE_MATCH .match (arg )
248+ if match :
249+ return match .group (1 )
250+
251+ match = RE_VARIABLE_MATCH .match (arg )
252+ if match :
253+ var = match .group (1 ).lower ()
254+
255+ if var == "guild_id" :
256+ try :
257+ return str (ctx .guild .id )
258+ except AttributeError :
259+ raise commands .UserInputError ("no guild id available" ) from None
260+
261+ match = RE_CONVERSION_MATCH .match (arg )
262+ if match :
263+ value , typ = match .groups ()
264+ try :
265+ converter = CONVERTERS [typ ]
266+ except KeyError :
267+ pass
268+ else :
269+ repl = await call_converter (converter , ctx , value )
270+ return str (repl .id )
271+
272+ return arg
273+
274+ async def substitute_variables (self , ctx : commands .Context , args : List [str ]) -> List [str ]:
275+ return await asyncio .gather (* (self .substitute_variable (ctx , arg ) for arg in args ))
276+
248277 @commands .command ("call" )
249278 async def call_cmd (self , ctx : commands .Context , * , args : str ) -> None :
250279 session = self ._cmd_get_session (ctx )
251280
281+ args = libwampli .split_arg_string (args )
282+ args = await self .substitute_variables (ctx , args )
252283 args , kwargs = libwampli .parse_args (args )
253284 libwampli .ready_uri (args )
254285
@@ -264,6 +295,8 @@ async def call_cmd(self, ctx: commands.Context, *, args: str) -> None:
264295 async def publish_cmd (self , ctx : commands .Context , * , args ) -> None :
265296 session = self ._cmd_get_session (ctx )
266297
298+ args = libwampli .split_arg_string (args )
299+ args = await self .substitute_variables (ctx , args )
267300 args , kwargs = libwampli .parse_args (args )
268301 libwampli .ready_uri (args )
269302
@@ -434,3 +467,25 @@ def maybe_wrap_yaml(s: str) -> str:
434467def discord_format (o : Any ) -> str :
435468 s = libwampli .human_result (o )
436469 return maybe_wrap_yaml (s )
470+
471+
472+ async def call_converter (converter : Type [commands .Converter ], ctx : commands .Context , arg : str ) -> Any :
473+ return await converter ().convert (ctx , arg )
474+
475+
476+ RE_SNOWFLAKE_MATCH : Pattern = re .compile (r"<[@#](\d+)>" )
477+
478+ RE_CONVERSION_MATCH : Pattern = re .compile (r"\((.+?)\) as (\w{2,})" )
479+
480+ CONVERTER_ALIASES : Dict [Type [commands .Converter ], Tuple [str , ...]] = {
481+ commands .TextChannelConverter : ("tc" , "channel" , "TextChannel" ),
482+ commands .VoiceChannelConverter : ("vc" , "VoiceChannel" ),
483+ }
484+
485+ CONVERTERS : Dict [str , Type [commands .Converter ]] = {
486+ key : converter
487+ for converter , keys in CONVERTER_ALIASES .items ()
488+ for key in keys
489+ }
490+
491+ RE_VARIABLE_MATCH : Pattern = re .compile (r"\$(\w{3,})" )
0 commit comments