def find_code_blocks(message: str) -> Optional[Sequence[CodeBlock]]: """ Find and return all Markdown code blocks in the `message`. Code blocks with 3 or fewer lines are excluded. If the `message` contains at least one code block with valid ticks and a specified language, return None. This is based on the assumption that if the user managed to get one code block right, they already know how to fix the rest themselves. """ log.trace("Finding all code blocks in a message.") code_blocks = [] for match in _RE_CODE_BLOCK.finditer(message): # Used to ensure non-matched groups have an empty string as the default value. groups = match.groupdict("") language = groups["lang"].strip() # Strip the newline cause it's included in the group. if groups["tick"] == BACKTICK and language: log.trace("Message has a valid code block with a language; returning None.") return None elif has_lines(groups["code"], constants.CodeBlock.minimum_lines): code_block = CodeBlock(groups["code"], language, groups["tick"]) code_blocks.append(code_block) else: log.trace("Skipped a code block shorter than 4 lines.") return code_blocks
def should_parse(self, message: discord.Message) -> bool: """ Return True if `message` should be parsed. A qualifying message: 1. Is not authored by a bot 2. Is in a valid channel 3. Has more than 3 lines 4. Has no bot or webhook token """ return (not message.author.bot and self.is_valid_channel(message.channel) and has_lines( message.content, constants.CodeBlock.minimum_lines) and not TokenRemover.find_token_in_message(message) and not WEBHOOK_URL_RE.search(message.content))