def test_apostrophes(): assert argsplit("foo bar") == ["foo", "bar"] assert argsplit("'foo bar'") == ["foo bar"] assert argsplit("foo's bar") == ["foo's", "bar"] assert argsplit('''"foo's bar"''') == ["foo's bar"] assert argsplit("el'ven'ame") == ["el'ven'ame"] assert argsplit("darius'") == ["darius'"] assert argsplit("Samus' Armor") == ["Samus'", "Armor"] with pytest.raises(ExpectedClosingQuoteError): argsplit("'tis") assert argsplit("'tis Jack's") == ["tis Jacks"] # weird
def test_argsplit(): assert argsplit("""foo bar "two words" yay!""") == [ "foo", "bar", "two words", "yay!" ] assert argsplit("""'some string here' in quotes""") == [ "some string here", "in", "quotes" ] assert argsplit(""""partial quoted"blocks""") == ["partial quotedblocks"] assert argsplit('''"'nested quotes'"''') == ["'nested quotes'"] assert argsplit("""-phrase "She said, \\"Hello world\\"" """) == [ "-phrase", 'She said, "Hello world"' ]
async def parse_snippets(args, ctx) -> str: """ Parses user and server snippets. :param args: The string to parse. Will be split automatically :param ctx: The Context. :return: The string, with snippets replaced. """ # make args a list of str if isinstance(args, str): args = argsplit(args) if not isinstance(args, list): args = list(args) for index, arg in enumerate(args): # parse snippets server_invoker = False # personal snippet/servsnippet the_snippet = await get_personal_snippet_named(ctx, arg) if the_snippet is None and ctx.guild is not None: the_snippet = await get_server_snippet_named(ctx, arg) server_invoker = True if isinstance(the_snippet, WorkshopSnippet): await workshop_entitlements_check(ctx, the_snippet) if the_snippet: args[index] = the_snippet.code # analytics await the_snippet.log_invocation(ctx, server_invoker) elif ' ' in arg: args[index] = argquote(arg) return " ".join(args)
async def handle_alias_arguments(self, command, message): """Takes an alias name, alias value, and message and handles percent-encoded args. Returns: string""" prefix = await self.bot.get_server_prefix(message) rawargs = " ".join(message.content[len(prefix):].split(' ')[1:]) args = argsplit(rawargs) tempargs = args[:] new_command = command if '%*%' in command: new_command = new_command.replace('%*%', argquote(rawargs)) tempargs = [] if '&*&' in command: new_command = new_command.replace('&*&', rawargs.replace("\"", "\\\"")) tempargs = [] if '&ARGS&' in command: new_command = new_command.replace('&ARGS&', str(args)) tempargs = [] for index, value in enumerate(args): key = '%{}%'.format(index + 1) to_remove = False if key in command: new_command = new_command.replace(key, argquote(value)) to_remove = True key = '&{}&'.format(index + 1) if key in command: new_command = new_command.replace(key, value.replace("\"", "\\\"")) to_remove = True if to_remove: try: tempargs.remove(value) except ValueError: pass quoted_args = ' '.join(map(argquote, tempargs)) return f"{prefix}{new_command} {quoted_args}".strip()
async def parse_snippets(args, ctx, statblock=None, character=None) -> str: """ Parses user and server snippets, including any inline scripting. :param args: The string to parse. Will be split automatically :param ctx: The Context. :param statblock: The statblock to populate locals from. :param character: If passed, provides the base character to use character-scoped functions against. :return: The string, with snippets replaced. """ # make args a list of str if isinstance(args, str): args = argsplit(args) if not isinstance(args, list): args = list(args) # set up the evaluator evaluator = await evaluators.ScriptingEvaluator.new(ctx) if character is not None: evaluator.with_character(character) elif statblock is not None: evaluator.with_statblock(statblock) try: for index, arg in enumerate(args): # parse snippets server_invoker = False # personal snippet/servsnippet the_snippet = await get_personal_snippet_named(ctx, arg) if the_snippet is None and ctx.guild is not None: the_snippet = await get_server_snippet_named(ctx, arg) server_invoker = True if isinstance(the_snippet, WorkshopSnippet): await workshop_entitlements_check(ctx, the_snippet) if the_snippet: # enter the evaluator execution_scope = ExecutionScope.SERVER_SNIPPET if server_invoker else ExecutionScope.PERSONAL_SNIPPET args[index] = await evaluator.transformed_str_async( the_snippet.code, execution_scope=execution_scope, invoking_object=the_snippet) # analytics await the_snippet.log_invocation(ctx, server_invoker) else: # in case the user is using old-style on the fly templating arg = await evaluator.transformed_str_async( arg, execution_scope=ExecutionScope.PERSONAL_SNIPPET) args[index] = argquote(arg) finally: await evaluator.run_commits() return " ".join(args)
async def parse_snippets(args, ctx) -> str: """ Parses user and server snippets. :param args: The string to parse. Will be split automatically :param ctx: The Context. :return: The string, with snippets replaced. """ if isinstance(args, str): args = argsplit(args) if not isinstance(args, list): args = list(args) servsnippets = await get_servsnippets(ctx) snippets = await get_snippets(ctx) for index, arg in enumerate(args): # parse snippets snippet = snippets.get(arg) snippet_value = None if snippet: await ctx.bot.mdb.analytics_alias_events.insert_one({ "type": "snippet", "object_id": snippet['_id'], "timestamp": datetime.datetime.utcnow(), "user_id": ctx.author.id }) snippet_value = snippet['snippet'] else: snippet = servsnippets.get(arg) if snippet: await ctx.bot.mdb.analytics_alias_events.insert_one({ "type": "servsnippet", "object_id": snippet['_id'], "timestamp": datetime.datetime.utcnow(), "user_id": ctx.author.id }) snippet_value = snippet['snippet'] if snippet_value: args[index] = snippet_value elif ' ' in arg: args[index] = argquote(arg) return " ".join(args)
async def parse_snippets(args, ctx) -> str: """ Parses user and server snippets. :param args: The string to parse. Will be split automatically :param ctx: The Context. :return: The string, with snippets replaced. """ if isinstance(args, str): args = argsplit(args) if not isinstance(args, list): args = list(args) snippets = await get_servsnippets(ctx) snippets.update(await get_snippets(ctx)) for index, arg in enumerate(args): # parse snippets snippet_value = snippets.get(arg) if snippet_value: args[index] = snippet_value elif ' ' in arg: args[index] = argquote(arg) return " ".join(args)
async def handle_alias_arguments(command, ctx): """Takes an alias name, alias value, and message and handles percent-encoded args. Returns: string""" prefix = ctx.prefix rawargs = ctx.view.read_rest().strip() args = argsplit(rawargs) tempargs = args[:] new_command = command if '%*%' in command: new_command = new_command.replace('%*%', argquote(rawargs)) tempargs = [] if '&*&' in command: new_command = new_command.replace('&*&', rawargs.replace("\"", "\\\"")) tempargs = [] if '&ARGS&' in command: new_command = new_command.replace('&ARGS&', str(args)) tempargs = [] for index, value in enumerate(args): key = '%{}%'.format(index + 1) to_remove = False if key in command: new_command = new_command.replace(key, argquote(value)) to_remove = True key = '&{}&'.format(index + 1) if key in command: new_command = new_command.replace(key, value.replace("\"", "\\\"")) to_remove = True if to_remove: try: tempargs.remove(value) except ValueError: pass quoted_args = ' '.join(map(argquote, tempargs)) return f"{prefix}{new_command} {quoted_args}".strip()
def test_argquote(): assert argquote("foo") == "foo" assert argquote("foo bar") == '"foo bar"' assert argquote('one "two three"') == '"one \\"two three\\""' assert argsplit(argquote('one "two three"')) == ['one "two three"']