diff options
| -rw-r--r-- | bot/constants.py | 9 | ||||
| -rw-r--r-- | bot/exts/evergreen/cheatsheet.py | 113 | ||||
| -rw-r--r-- | bot/exts/evergreen/status_cats.py | 33 | ||||
| -rw-r--r-- | bot/exts/evergreen/status_codes.py | 71 | ||||
| -rw-r--r-- | bot/exts/evergreen/wolfram.py | 11 | ||||
| -rw-r--r-- | docker-compose.yml | 8 | 
6 files changed, 198 insertions, 47 deletions
diff --git a/bot/constants.py b/bot/constants.py index 1234ef3b..bb538487 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -106,12 +106,6 @@ class Channels(NamedTuple):      devlog = int(environ.get("CHANNEL_DEVLOG", 622895325144940554))      dev_contrib = 635950537262759947      dev_branding = 753252897059373066 -    help_0 = 303906576991780866 -    help_1 = 303906556754395136 -    help_2 = 303906514266226689 -    help_3 = 439702951246692352 -    help_4 = 451312046647148554 -    help_5 = 454941769734422538      helpers = 385474242440986624      message_log = 467752170159079424      mod_alerts = 473092532147060736 @@ -133,6 +127,7 @@ class Channels(NamedTuple):  class Categories(NamedTuple): +    help_in_use = 696958401460043776      development = 411199786025484308      devprojects = 787641585624940544      media = 799054581991997460 @@ -248,7 +243,6 @@ class Roles(NamedTuple):      announcements = 463658397560995840      champion = 430492892331769857      contributor = 295488872404484098 -    developer = 352427296948486144      devops = 409416496733880320      jammer = 423054537079783434      moderator = 267629731250176001 @@ -259,6 +253,7 @@ class Roles(NamedTuple):      rockstars = 458226413825294336      core_developers = 587606783669829632      events_lead = 778361735739998228 +    everyone_role = 267624335836053506  class Tokens(NamedTuple): diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py new file mode 100644 index 00000000..a64ddd69 --- /dev/null +++ b/bot/exts/evergreen/cheatsheet.py @@ -0,0 +1,113 @@ +import random +import re +import typing as t +from urllib.parse import quote_plus + +from discord import Embed +from discord.ext import commands +from discord.ext.commands import BucketType, Context + +from bot import constants +from bot.constants import Categories, Channels, Colours, ERROR_REPLIES, Roles, WHITELISTED_CHANNELS +from bot.utils.decorators import with_role + +ERROR_MESSAGE = f""" +Unknown cheat sheet. Please try to reformulate your query. + +**Examples**: +```md +{constants.Client.prefix}cht read json +{constants.Client.prefix}cht hello world +{constants.Client.prefix}cht lambda +``` +If the problem persists send a message in <#{Channels.dev_contrib}> +""" + +URL = 'https://cheat.sh/python/{search}' +ESCAPE_TT = str.maketrans({"`": "\\`"}) +ANSI_RE = re.compile(r"\x1b\[.*?m") +# We need to pass headers as curl otherwise it would default to aiohttp which would return raw html. +HEADERS = {'User-Agent': 'curl/7.68.0'} + + +class CheatSheet(commands.Cog): +    """Commands that sends a result of a cht.sh search in code blocks.""" + +    def __init__(self, bot: commands.Bot): +        self.bot = bot + +    @staticmethod +    def fmt_error_embed() -> Embed: +        """ +        Format the Error Embed. + +        If the cht.sh search returned 404, overwrite it to send a custom error embed. +        link -> https://github.com/chubin/cheat.sh/issues/198 +        """ +        embed = Embed( +            title=random.choice(ERROR_REPLIES), +            description=ERROR_MESSAGE, +            colour=Colours.soft_red +        ) +        return embed + +    def result_fmt(self, url: str, body_text: str) -> t.Tuple[bool, t.Union[str, Embed]]: +        """Format Result.""" +        if body_text.startswith("#  404 NOT FOUND"): +            embed = self.fmt_error_embed() +            return True, embed + +        body_space = min(1986 - len(url), 1000) + +        if len(body_text) > body_space: +            description = (f"**Result Of cht.sh**\n" +                           f"```python\n{body_text[:body_space]}\n" +                           f"... (truncated - too many lines)```\n" +                           f"Full results: {url} ") +        else: +            description = (f"**Result Of cht.sh**\n" +                           f"```python\n{body_text}```\n" +                           f"{url}") +        return False, description + +    @commands.command( +        name="cheat", +        aliases=("cht.sh", "cheatsheet", "cheat-sheet", "cht"), +    ) +    @commands.cooldown(1, 10, BucketType.user) +    @with_role(Roles.everyone_role) +    async def cheat_sheet(self, ctx: Context, *search_terms: str) -> None: +        """ +        Search cheat.sh. + +        Gets a post from https://cheat.sh/python/ by default. +        Usage: +        --> .cht read json +        """ +        if not ( +                ctx.channel.category.id == Categories.help_in_use +                or ctx.channel.id in WHITELISTED_CHANNELS +        ): +            return + +        async with ctx.typing(): +            search_string = quote_plus(" ".join(search_terms)) + +            async with self.bot.http_session.get( +                    URL.format(search=search_string), headers=HEADERS +            ) as response: +                result = ANSI_RE.sub("", await response.text()).translate(ESCAPE_TT) + +            is_embed, description = self.result_fmt( +                URL.format(search=search_string), +                result +            ) +            if is_embed: +                await ctx.send(embed=description) +            else: +                await ctx.send(content=description) + + +def setup(bot: commands.Bot) -> None: +    """Load the CheatSheet cog.""" +    bot.add_cog(CheatSheet(bot)) diff --git a/bot/exts/evergreen/status_cats.py b/bot/exts/evergreen/status_cats.py deleted file mode 100644 index 586b8378..00000000 --- a/bot/exts/evergreen/status_cats.py +++ /dev/null @@ -1,33 +0,0 @@ -from http import HTTPStatus - -import discord -from discord.ext import commands - - -class StatusCats(commands.Cog): -    """Commands that give HTTP statuses described and visualized by cats.""" - -    def __init__(self, bot: commands.Bot): -        self.bot = bot - -    @commands.command(aliases=['statuscat']) -    async def http_cat(self, ctx: commands.Context, code: int) -> None: -        """Sends an embed with an image of a cat, potraying the status code.""" -        embed = discord.Embed(title=f'**Status: {code}**') - -        try: -            HTTPStatus(code) - -        except ValueError: -            embed.set_footer(text='Inputted status code does not exist.') - -        else: -            embed.set_image(url=f'https://http.cat/{code}.jpg') - -        finally: -            await ctx.send(embed=embed) - - -def setup(bot: commands.Bot) -> None: -    """Load the StatusCats cog.""" -    bot.add_cog(StatusCats(bot)) diff --git a/bot/exts/evergreen/status_codes.py b/bot/exts/evergreen/status_codes.py new file mode 100644 index 00000000..874c87eb --- /dev/null +++ b/bot/exts/evergreen/status_codes.py @@ -0,0 +1,71 @@ +from http import HTTPStatus + +import discord +from discord.ext import commands + +HTTP_DOG_URL = "https://httpstatusdogs.com/img/{code}.jpg" +HTTP_CAT_URL = "https://http.cat/{code}.jpg" + + +class HTTPStatusCodes(commands.Cog): +    """Commands that give HTTP statuses described and visualized by cats and dogs.""" + +    def __init__(self, bot: commands.Bot): +        self.bot = bot + +    @commands.group(name="http_status", aliases=("status", "httpstatus")) +    async def http_status_group(self, ctx: commands.Context) -> None: +        """Group containing dog and cat http status code commands.""" +        if not ctx.invoked_subcommand: +            await ctx.send_help(ctx.command) + +    @http_status_group.command(name='cat') +    async def http_cat(self, ctx: commands.Context, code: int) -> None: +        """Sends an embed with an image of a cat, portraying the status code.""" +        embed = discord.Embed(title=f'**Status: {code}**') +        url = HTTP_CAT_URL.format(code=code) + +        try: +            HTTPStatus(code) +            async with self.bot.http_session.get(url, allow_redirects=False) as response: +                if response.status != 404: +                    embed.set_image(url=url) +                else: +                    raise NotImplementedError + +        except ValueError: +            embed.set_footer(text='Inputted status code does not exist.') + +        except NotImplementedError: +            embed.set_footer(text='Inputted status code is not implemented by http.cat yet.') + +        finally: +            await ctx.send(embed=embed) + +    @http_status_group.command(name='dog') +    async def http_dog(self, ctx: commands.Context, code: int) -> None: +        """Sends an embed with an image of a dog, portraying the status code.""" +        embed = discord.Embed(title=f'**Status: {code}**') +        url = HTTP_DOG_URL.format(code=code) + +        try: +            HTTPStatus(code) +            async with self.bot.http_session.get(url, allow_redirects=False) as response: +                if response.status != 302: +                    embed.set_image(url=url) +                else: +                    raise NotImplementedError + +        except ValueError: +            embed.set_footer(text='Inputted status code does not exist.') + +        except NotImplementedError: +            embed.set_footer(text='Inputted status code is not implemented by httpstatusdogs.com yet.') + +        finally: +            await ctx.send(embed=embed) + + +def setup(bot: commands.Bot) -> None: +    """Load the HTTPStatusCodes cog.""" +    bot.add_cog(HTTPStatusCodes(bot)) diff --git a/bot/exts/evergreen/wolfram.py b/bot/exts/evergreen/wolfram.py index 898e8d2a..437d9e1a 100644 --- a/bot/exts/evergreen/wolfram.py +++ b/bot/exts/evergreen/wolfram.py @@ -108,7 +108,10 @@ async def get_pod_pages(ctx: Context, bot: commands.Bot, query: str) -> Optional              "input": query,              "appid": APPID,              "output": DEFAULT_OUTPUT_FORMAT, -            "format": "image,plaintext" +            "format": "image,plaintext", +            "location": "the moon", +            "latlong": "0.0,0.0", +            "ip": "1.1.1.1"          })          request_url = QUERY.format(request="query", data=url_str) @@ -168,6 +171,9 @@ class Wolfram(Cog):          url_str = parse.urlencode({              "i": query,              "appid": APPID, +            "location": "the moon", +            "latlong": "0.0,0.0", +            "ip": "1.1.1.1"          })          query = QUERY.format(request="simple", data=url_str) @@ -248,6 +254,9 @@ class Wolfram(Cog):          url_str = parse.urlencode({              "i": query,              "appid": APPID, +            "location": "the moon", +            "latlong": "0.0,0.0", +            "ip": "1.1.1.1"          })          query = QUERY.format(request="result", data=url_str) diff --git a/docker-compose.yml b/docker-compose.yml index bb6ad6ac..a18534a5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,13 +12,9 @@ services:        - redis      environment: -      - BOT_TOKEN -      - BOT_DEBUG -      - BOT_GUILD -      - BOT_ADMIN_ROLE_ID -      - CHANNEL_DEVLOG -      - CHANNEL_COMMUNITY_BOT_COMMANDS        - REDIS_HOST=redis +    env_file: +      - .env      volumes:        - .:/bot  |