diff options
| author | 2018-09-28 11:00:21 +0200 | |
|---|---|---|
| committer | 2018-09-28 11:00:21 +0200 | |
| commit | d4a2ff17e6b6b2224ad7355cd0e635cdb20db9cf (patch) | |
| tree | 7e559681f7bf9c250f52af28342a2fb25e23d94e | |
| parent | improving a comment. why is this a commit. I'm so sorry. (diff) | |
| parent | maybe next time the mod log breaks we can fix it before it's been 2 weeks. I'... (diff) | |
Merge branch 'master' of gitlab.com:python-discord/projects/bot
| -rw-r--r-- | bot/cogs/filtering.py | 4 | ||||
| -rw-r--r-- | bot/cogs/modlog.py | 2 | ||||
| -rw-r--r-- | bot/cogs/snekbox.py | 43 | ||||
| -rw-r--r-- | bot/cogs/tags.py | 25 | 
4 files changed, 53 insertions, 21 deletions
| diff --git a/bot/cogs/filtering.py b/bot/cogs/filtering.py index 586c99174..70254fd88 100644 --- a/bot/cogs/filtering.py +++ b/bot/cogs/filtering.py @@ -111,8 +111,8 @@ class Filtering:                          message = (                              f"The {filter_name} {_filter['type']} was triggered "                              f"by **{msg.author.name}#{msg.author.discriminator}** " -                            f"(`{msg.author.id}`) in <#{msg.channel.id}> with the " -                            f"following message:\n\n" +                            f"(`{msg.author.id}`) in <#{msg.channel.id}> with [the " +                            f"following message]({msg.jump_url}):\n\n"                              f"{msg.content}"                          ) diff --git a/bot/cogs/modlog.py b/bot/cogs/modlog.py index d302634d1..9c81661ba 100644 --- a/bot/cogs/modlog.py +++ b/bot/cogs/modlog.py @@ -360,7 +360,7 @@ class ModLog:          now = datetime.datetime.utcnow()          difference = abs(relativedelta(now, member.created_at)) -        message += "\n\n**Account age:** " + humanize_delta(member.created_at) +        message += "\n\n**Account age:** " + humanize_delta(difference)          if difference.days < 1 and difference.months < 1 and difference.years < 1:  # New user account!              message = f"{Emojis.new} {message}" diff --git a/bot/cogs/snekbox.py b/bot/cogs/snekbox.py index 6f618a2c7..fb9164194 100644 --- a/bot/cogs/snekbox.py +++ b/bot/cogs/snekbox.py @@ -32,6 +32,23 @@ except Exception as e:  """  ESCAPE_REGEX = re.compile("[`\u202E\u200B]{3,}") +FORMATTED_CODE_REGEX = re.compile( +    r"^\s*"                                 # any leading whitespace from the beginning of the string +    r"(?P<delim>(?P<block>```)|``?)"        # code delimiter: 1-3 backticks; (?P=block) only matches if it's a block +    r"(?(block)(?:(?P<lang>[a-z]+)\n)?)"    # if we're in a block, match optional language (only letters plus newline) +    r"(?:[ \t]*\n)*"                        # any blank (empty or tabs/spaces only) lines before the code +    r"(?P<code>.*?)"                        # extract all code inside the markup +    r"\s*"                                  # any more whitespace before the end of the code markup +    r"(?P=delim)"                           # match the exact same delimiter from the start again +    r"\s*$",                                # any trailing whitespace until the end of the string +    re.DOTALL | re.IGNORECASE               # "." also matches newlines, case insensitive +) +RAW_CODE_REGEX = re.compile( +    r"^(?:[ \t]*\n)*"                       # any blank (empty or tabs/spaces only) lines before the code +    r"(?P<code>.*?)"                        # extract all the rest as code +    r"\s*$",                                # any trailing whitespace until the end of the string +    re.DOTALL                               # "." also matches newlines +)  BYPASS_ROLES = (Roles.owner, Roles.admin, Roles.moderator, Roles.helpers)  WHITELISTED_CHANNELS = (Channels.bot,)  WHITELISTED_CHANNELS_STRING = ', '.join(f"<#{channel_id}>" for channel_id in WHITELISTED_CHANNELS) @@ -54,8 +71,6 @@ class Snekbox:      Safe evaluation using Snekbox      """ -    jobs = None  # type: dict -      def __init__(self, bot: Bot):          self.bot = bot          self.jobs = {} @@ -85,18 +100,20 @@ class Snekbox:          log.info(f"Received code from {ctx.author.name}#{ctx.author.discriminator} for evaluation:\n{code}")          self.jobs[ctx.author.id] = datetime.datetime.now() -        while code.startswith("\n"): -            code = code[1:] - -        if code.startswith("```") and code.endswith("```"): -            code = code[3:-3] - -        if code.startswith("python"): -            code = code[6:] -        elif code.startswith("py"): -            code = code[2:] +        # Strip whitespace and inline or block code markdown and extract the code and some formatting info +        match = FORMATTED_CODE_REGEX.fullmatch(code) +        if match: +            code, block, lang, delim = match.group("code", "block", "lang", "delim") +            code = textwrap.dedent(code) +            if block: +                info = (f"'{lang}' highlighted" if lang else "plain") + " code block" +            else: +                info = f"{delim}-enclosed inline code" +            log.trace(f"Extracted {info} for evaluation:\n{code}") +        else: +            code = textwrap.dedent(RAW_CODE_REGEX.fullmatch(code).group("code")) +            log.trace(f"Eval message contains not or badly formatted code, stripping whitespace only:\n{code}") -        code = textwrap.dedent(code.strip())          code = textwrap.indent(code, "    ")          code = CODE_TEMPLATE.replace("{CODE}", code) diff --git a/bot/cogs/tags.py b/bot/cogs/tags.py index 7499b2b1c..e6f9ecd89 100644 --- a/bot/cogs/tags.py +++ b/bot/cogs/tags.py @@ -1,6 +1,7 @@  import logging  import random  import time +from typing import Optional  from discord import Colour, Embed  from discord.ext.commands import ( @@ -11,6 +12,7 @@ from discord.ext.commands import (  from bot.constants import (      Channels, Cooldowns, ERROR_REPLIES, Keys, Roles, URLs  ) +from bot.converters import ValidURL  from bot.decorators import with_role  from bot.pagination import LinePaginator @@ -107,12 +109,13 @@ class Tags:          return tag_data -    async def post_tag_data(self, tag_name: str, tag_content: str) -> dict: +    async def post_tag_data(self, tag_name: str, tag_content: str, image_url: Optional[str]) -> dict:          """          Send some tag_data to our API to have it saved in the database.          :param tag_name: The name of the tag to create or edit.          :param tag_content: The content of the tag. +        :param image_url: The image URL of the tag, can be `None`.          :return: json response from the API in the following format:          {              'success': bool @@ -121,7 +124,8 @@ class Tags:          params = {              'tag_name': tag_name, -            'tag_content': tag_content +            'tag_content': tag_content, +            'image_url': image_url          }          response = await self.bot.http_session.post(URLs.site_tags_api, headers=self.headers, json=params) @@ -226,6 +230,8 @@ class Tags:              else:                  embed.description = tag_data['tag_content'] +                if tag_data['image_url'] is not None: +                    embed.set_image(url=tag_data['image_url'])          # If not, prepare an error message.          else: @@ -257,13 +263,20 @@ class Tags:      @tags_group.command(name='set', aliases=('add', 'edit', 's'))      @with_role(Roles.admin, Roles.owner, Roles.moderator) -    async def set_command(self, ctx: Context, tag_name: TagNameConverter, *, tag_content: TagContentConverter): +    async def set_command( +        self, +        ctx: Context, +        tag_name: TagNameConverter, +        tag_content: TagContentConverter, +        image_url: ValidURL = None +    ):          """          Create a new tag or edit an existing one.          :param ctx: discord message context          :param tag_name: The name of the tag to create or edit.          :param tag_content: The content of the tag. +        :param image_url: An optional image for the tag.          """          tag_name = tag_name.lower().strip() @@ -271,12 +284,13 @@ class Tags:          embed = Embed()          embed.colour = Colour.red() -        tag_data = await self.post_tag_data(tag_name, tag_content) +        tag_data = await self.post_tag_data(tag_name, tag_content, image_url)          if tag_data.get("success"):              log.debug(f"{ctx.author} successfully added the following tag to our database: \n"                        f"tag_name: {tag_name}\n" -                      f"tag_content: '{tag_content}'") +                      f"tag_content: '{tag_content}'\n" +                      f"image_url: '{image_url}'")              embed.colour = Colour.blurple()              embed.title = "Tag successfully added"              embed.description = f"**{tag_name}** added to tag database." @@ -284,6 +298,7 @@ class Tags:              log.error("There was an unexpected database error when trying to add the following tag: \n"                        f"tag_name: {tag_name}\n"                        f"tag_content: '{tag_content}'\n" +                      f"image_url: '{image_url}'\n"                        f"response: {tag_data}")              embed.title = "Database error"              embed.description = ("There was a problem adding the data to the tags database. " | 
