diff options
| -rw-r--r-- | bot/__init__.py | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/bot/__init__.py b/bot/__init__.py index 76cab5a74..40c4eefdc 100644 --- a/bot/__init__.py +++ b/bot/__init__.py @@ -95,7 +95,7 @@ def _get_word(self) -> str: while not self.eof: try: current = self.buffer[self.index + pos] - if current.isspace() or current == "(": + if current.isspace() or current == "(" or current == "[": break pos += 1 except IndexError: @@ -171,6 +171,61 @@ def _get_word(self) -> str: result = self.buffer[self.previous:self.index + (pos+2)] self.index += 2 + # Check if a command in the form of `bot.tags['ask']` + # or alternatively `bot.tags['ask'] = 'whatever'` was used. + elif current == "[": + def clean_argument(arg: str) -> str: + """Helper function to remove any characters we don't care about.""" + + return arg.strip("[]'\" ").replace('"', '\\"') + + log.trace(f"Got a command candidate for getitem / setitem mimick: {self.buffer}") + # Syntax is `bot.tags['ask']` => mimic `getattr` + if self.buffer.endswith("]"): + # Key: The first argument, specified `bot.tags[here]` + key = clean_argument(self.buffer[self.index:]) + log.trace(f"Command mimicks getitem. Key: {key!r}") + + # note: if not key, this corresponds to an empty argument + # so this should throw / return a SyntaxError ? + args = f'"{key}"' + + # Use the cog's `get` command. + result = self.buffer[self.previous:self.index] + ".get" + + # Syntax is `bot.tags['ask'] = 'whatever'` => mimic `setattr` + elif "=" in self.buffer and not self.buffer.endswith("="): + equals_pos = self.buffer.find("=") + + # Key: The first argument, specified `bot.tags[here]` + key = clean_argument(self.buffer[self.index:equals_pos]) + + # Value: The second argument, specified after the `=` + value = ( + clean_argument( + self.buffer.split("=")[1] + ) + .replace("'", "\\'") # escape any unescaped quotes + ) + log.trace(f"Command mimicks setitem. Key: {key!r}, value: {value!r}.") + + # Use the cog's `set` command. + result = self.buffer[self.previous:self.index] + ".set" + args = f'"{key}" "{value}"' + + # Syntax is god knows what, pass it along + # in the future, this should probably return / throw SyntaxError + else: + result = self.buffer + args = '' + log.trace(f"Command is of unknown syntax: {self.buffer}") + + # Reconstruct valid discord.py syntax + self.buffer = f"{result} {args}" + self.index = len(result) + self.end = len(self.buffer) + log.trace(f"Mimicked command: {self.buffer}") + if isinstance(result, str): return result.lower() # Case insensitivity, baby return result |