Exemple #1
0
def argsplit(args):
    view = StringView(args)
    args = []
    while not view.eof:
        view.skip_ws()
        args.append(quoted_word(view))
    return args
Exemple #2
0
 def get_extra_args_from_alias(
     self, message: discord.Message, prefix: str, alias: AliasEntry
 ) -> str:
     """
     When an alias is executed by a user in chat this function tries
         to get any extra arguments passed in with the call.
         Whitespace will be trimmed from both ends.
     :param message: 
     :param prefix: 
     :param alias: 
     :return: 
     """
     known_content_length = len(prefix) + len(alias.name)
     extra = message.content[known_content_length:]
     view = StringView(extra)
     view.skip_ws()
     extra = []
     while not view.eof:
         prev = view.index
         word = quoted_word(view)
         if len(word) < view.index - prev:
             word = "".join((view.buffer[prev], word, view.buffer[view.index - 1]))
         extra.append(word)
         view.skip_ws()
     return extra
Exemple #3
0
    async def on_message(self, message):
        if message.author.bot or not self.bot.is_running():
            return
        if message.content.startswith(self.bot.command_prefix):
            name = message.content.lower().lstrip(self.bot.command_prefix).split(" ")[0]
            if command := config.Commands.fetch(name):
                attachment = None
                if command["attachment"]:
                    async with aiohttp.ClientSession() as session:
                        async with session.get(command["attachment"]) as resp:
                            buff = io.BytesIO(await resp.read())
                            attachment = discord.File(filename=command["attachment"].split("/")[-1], fp=buff)
                args = []
                view = StringView(message.content.lstrip(self.bot.command_prefix))
                view.get_word()  # command name
                while not view.eof:
                    view.skip_ws()
                    args.append(view.get_quoted_word())

                text = re.sub(
                    r'{(\d+)}',
                    lambda match: args[int(match.group(1))]
                    if int(match.group(1)) < len(args)
                    else '(missing argument)',
                    command["content"]
                ).replace('{...}', ' '.join(args))

                await self.bot.reply_to_msg(message, text, file=attachment)
                return
Exemple #4
0
 async def exec(self, ctx, *, code):
     """Remote executes code."""
     code = code.strip()
     py_start = code.lower().startswith("```py")
     python_start = py_start and code.lower().startswith("```python")
     view = StringView(code)
     view.skip_string(ctx.prefix)
     view.skip_ws()
     view.skip_string(ctx.invoked_with)
     view.skip_ws()
     code = view.read_rest()
     if python_start:
         code = code[9:]
     elif py_start:
         code = code[5:]
     elif code.startswith("```"):
         code = code[3:]
     if code.endswith("```"):
         code = code[:-3]
     del py_start, python_start, view
     with closing(StringIO()) as log:
         with redirect_stdout(log):
             try:
                 exec(code)
             except Exception:
                 error = exc_info()
                 for e in error:
                     print(e)
         output = log.getvalue()
     output = "```\n" + output + "```"
     await reply(ctx, output)
Exemple #5
0
    def handle_alias_arguments(self, command, message):
        """Takes an alias name, alias value, and message and handles percent-encoded args.
        Returns: string"""
        rawargs = " ".join(self.bot.prefix.join(message.content.split(self.bot.prefix)[1:]).split(' ')[1:])
        view = StringView(rawargs)
        args = []
        while not view.eof:
            view.skip_ws()
            args.append(quoted_word(view))
        tempargs = args[:]
        new_command = command
        if '%*%' in command:
            new_command = new_command.replace('%*%', shlex.quote(rawargs) if ' ' in rawargs else rawargs)
            tempargs = []
        if '&*&' in command:
            new_command = new_command.replace('&*&', rawargs.replace("\"", "\\\"").replace("'", "\\'"))
            tempargs = []
        for index, value in enumerate(args):
            key = '%{}%'.format(index + 1)
            to_remove = False
            if key in command:
                new_command = new_command.replace(key, shlex.quote(value) if ' ' in value else value)
                to_remove = True
            key = '&{}&'.format(index + 1)
            if key in command:
                new_command = new_command.replace(key, value.replace("\"", "\\\"").replace("'", "\\'"))
                to_remove = True
            if to_remove:
                try:
                    tempargs.remove(value)
                except ValueError:
                    pass

        return self.bot.prefix + new_command + " " + ' '.join((shlex.quote(v) if ' ' in v else v) for v in tempargs)
Exemple #6
0
 def get_extra_args_from_alias(self, message: discord.Message, prefix: str,
                               alias: AliasEntry) -> str:
     """
     When an alias is executed by a user in chat this function tries
         to get any extra arguments passed in with the call.
         Whitespace will be trimmed from both ends.
     :param message: 
     :param prefix: 
     :param alias: 
     :return: 
     """
     known_content_length = len(prefix) + len(alias.name)
     extra = message.content[known_content_length:]
     view = StringView(extra)
     view.skip_ws()
     extra = []
     while not view.eof:
         prev = view.index
         word = quoted_word(view)
         if len(word) < view.index - prev:
             word = "".join(
                 (view.buffer[prev], word, view.buffer[view.index - 1]))
         extra.append(word)
         view.skip_ws()
     return extra
Exemple #7
0
 async def convert(self, ctx, argument):
     converted = []
     view = StringView(argument)
     while not view.eof:
         args = []
         for converter in self.converters:
             view.skip_ws()
             arg = view.get_quoted_word()
             if arg is None:
                 raise commands.UserInputError(_('Not enough arguments.'))
             args.append(await self._do_conversion(ctx, converter, arg))
         converted.append(tuple(args))
     return converted
Exemple #8
0
async def _get_roles_from_content(ctx, content):
    # greedy = Greedy[RoleConverter]
    view = StringView(content)
    rc = RoleConverter()

    # "Borrowed" from discord.ext.commands.Command._transform_greedy_pos
    result = []
    while not view.eof:
        # for use with a manual undo
        previous = view.index

        view.skip_ws()
        try:
            argument = view.get_quoted_word()
            value = await rc.convert(ctx, argument)
        except (CommandError, ArgumentParsingError):
            view.index = previous
            break
        else:
            result.append(value)

    return [r.id for r in result]
Exemple #9
0
 def words(view: StringView) -> Generator[str, None, None]:
     """Yields each argument from a given StringView."""
     while not view.eof:
         view.skip_ws()
         yield quoted_word(view)