From c60c8471b4e0cb9b54bee80fd43c75c4a2e75b76 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Sun, 31 Jan 2021 15:13:58 +0530 Subject: [PATCH 01/11] Fix import order --- bot/exts/evergreen/cheatsheet.py | 93 ++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 bot/exts/evergreen/cheatsheet.py diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py new file mode 100644 index 0000000000..3a6890054b --- /dev/null +++ b/bot/exts/evergreen/cheatsheet.py @@ -0,0 +1,93 @@ +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.constants import Channels, Colours, ERROR_REPLIES + +ERROR_MESSAGE = """ +Unknown cheat sheet. Please try to reformulate your query. + +**Examples**: +```md +.cht read json +.cht hello world +.cht lambda +``` +If the problem persists send a message in <#{channel}> +""" + + +class ChtSh(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: + """If the cht.sh search returned 404, overwrite it to send a custom error embed.""" + embed = Embed(colour=Colours.soft_red) + embed.title = random.choice(ERROR_REPLIES) + embed.description = ERROR_MESSAGE.format(channel=Channels.dev_contrib) + 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) + 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 + """ + url = f'https://cheat.sh/python/{quote_plus(" ".join(search_terms))}' + headers = { + 'User-Agent': 'curl/7.68.0' + } + + escape_tt = str.maketrans({"`": "\\`"}) + ansi_re = re.compile(r"\x1b\[.*?m") + + async with self.bot.http_session.get(url, headers=headers) as response: + result = ansi_re.sub("", await response.text()).translate(escape_tt) + + is_embed, desciprtion = self.result_fmt(url, result) + if is_embed: + await ctx.send(embed=desciprtion) + else: + await ctx.send(content=desciprtion) + + +def setup(bot: commands.Bot) -> None: + """Load the ChtSh cog.""" + bot.add_cog(ChtSh(bot)) From a602361492cc653f8fae82a3b30f36b232ba5024 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Mon, 1 Feb 2021 05:18:28 +0530 Subject: [PATCH 02/11] Rename cog CheatSheet ; Change Embed code to a single constructor ; remove headers as chubin/cheat.sh#280 got merged ; improve error embed docstrings --- bot/exts/evergreen/cheatsheet.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py index 3a6890054b..211b324605 100644 --- a/bot/exts/evergreen/cheatsheet.py +++ b/bot/exts/evergreen/cheatsheet.py @@ -22,7 +22,7 @@ """ -class ChtSh(commands.Cog): +class CheatSheet(commands.Cog): """Commands that sends a result of a cht.sh search in code blocks.""" def __init__(self, bot: commands.Bot): @@ -30,10 +30,17 @@ def __init__(self, bot: commands.Bot): @staticmethod def fmt_error_embed() -> Embed: - """If the cht.sh search returned 404, overwrite it to send a custom error embed.""" - embed = Embed(colour=Colours.soft_red) - embed.title = random.choice(ERROR_REPLIES) - embed.description = ERROR_MESSAGE.format(channel=Channels.dev_contrib) + """ + 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.format(channel=Channels.dev_contrib), + colour=Colours.soft_red + ) return embed def result_fmt(self, url: str, body_text: str) -> t.Tuple[bool, t.Union[str, Embed]]: @@ -71,23 +78,20 @@ async def cheat_sheet( --> .cht read json """ url = f'https://cheat.sh/python/{quote_plus(" ".join(search_terms))}' - headers = { - 'User-Agent': 'curl/7.68.0' - } escape_tt = str.maketrans({"`": "\\`"}) ansi_re = re.compile(r"\x1b\[.*?m") - async with self.bot.http_session.get(url, headers=headers) as response: + async with self.bot.http_session.get(url) as response: result = ansi_re.sub("", await response.text()).translate(escape_tt) - is_embed, desciprtion = self.result_fmt(url, result) + is_embed, description = self.result_fmt(url, result) if is_embed: - await ctx.send(embed=desciprtion) + await ctx.send(embed=description) else: - await ctx.send(content=desciprtion) + await ctx.send(content=description) def setup(bot: commands.Bot) -> None: - """Load the ChtSh cog.""" - bot.add_cog(ChtSh(bot)) + """Load the CheatSheet cog.""" + bot.add_cog(CheatSheet(bot)) From 5c4cbbeeb5fd9e7f7c651b24b2b1d3bdbcc55110 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Tue, 2 Feb 2021 05:09:29 +0530 Subject: [PATCH 03/11] Make use of constants --- bot/exts/evergreen/cheatsheet.py | 39 +++++++++++++++++--------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py index 211b324605..4191a83fa5 100644 --- a/bot/exts/evergreen/cheatsheet.py +++ b/bot/exts/evergreen/cheatsheet.py @@ -7,20 +7,25 @@ from discord.ext import commands from discord.ext.commands import BucketType, Context +from bot import constants from bot.constants import Channels, Colours, ERROR_REPLIES -ERROR_MESSAGE = """ +ERROR_MESSAGE = f""" Unknown cheat sheet. Please try to reformulate your query. **Examples**: ```md -.cht read json -.cht hello world -.cht lambda +{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 <#{channel}> +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") + class CheatSheet(commands.Cog): """Commands that sends a result of a cht.sh search in code blocks.""" @@ -38,7 +43,7 @@ def fmt_error_embed() -> Embed: """ embed = Embed( title=random.choice(ERROR_REPLIES), - description=ERROR_MESSAGE.format(channel=Channels.dev_contrib), + description=ERROR_MESSAGE, colour=Colours.soft_red ) return embed @@ -67,9 +72,7 @@ def result_fmt(self, url: str, body_text: str) -> t.Tuple[bool, t.Union[str, Emb aliases=("cht.sh", "cheatsheet", "cheat-sheet", "cht"), ) @commands.cooldown(1, 10, BucketType.user) - async def cheat_sheet( - self, ctx: Context, *search_terms: str - ) -> None: + async def cheat_sheet(self, ctx: Context, *search_terms: str) -> None: """ Search cheat.sh. @@ -77,15 +80,15 @@ async def cheat_sheet( Usage: --> .cht read json """ - url = f'https://cheat.sh/python/{quote_plus(" ".join(search_terms))}' - - escape_tt = str.maketrans({"`": "\\`"}) - ansi_re = re.compile(r"\x1b\[.*?m") - - async with self.bot.http_session.get(url) as response: - result = ansi_re.sub("", await response.text()).translate(escape_tt) - - is_embed, description = self.result_fmt(url, result) + async with self.bot.http_session.get( + URL.format(search=quote_plus(" ".join(search_terms))) + ) as response: + result = ANSI_RE.sub("", await response.text()).translate(ESCAPE_TT) + + is_embed, description = self.result_fmt( + URL.format(search=quote_plus(" ".join(search_terms))), + result + ) if is_embed: await ctx.send(embed=description) else: From 2631004f7d1467bc81090ac481de78cbfe7978e5 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Tue, 2 Feb 2021 05:14:34 +0530 Subject: [PATCH 04/11] Add override_in_channel deco --- bot/exts/evergreen/cheatsheet.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py index 4191a83fa5..c83af839d0 100644 --- a/bot/exts/evergreen/cheatsheet.py +++ b/bot/exts/evergreen/cheatsheet.py @@ -8,7 +8,8 @@ from discord.ext.commands import BucketType, Context from bot import constants -from bot.constants import Channels, Colours, ERROR_REPLIES +from bot.constants import Channels, Colours, ERROR_REPLIES, WHITELISTED_CHANNELS +from bot.utils.decorators import override_in_channel ERROR_MESSAGE = f""" Unknown cheat sheet. Please try to reformulate your query. @@ -71,6 +72,7 @@ def result_fmt(self, url: str, body_text: str) -> t.Tuple[bool, t.Union[str, Emb name="cheat", aliases=("cht.sh", "cheatsheet", "cheat-sheet", "cht"), ) + @override_in_channel(WHITELISTED_CHANNELS) @commands.cooldown(1, 10, BucketType.user) async def cheat_sheet(self, ctx: Context, *search_terms: str) -> None: """ From 3e884eaa43b78b433a470aaff39b03a0f6c2b3c2 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Tue, 2 Feb 2021 06:05:46 +0530 Subject: [PATCH 05/11] Allow cht.sh command to be used in occupied help channels --- bot/constants.py | 11 +++++------ bot/exts/evergreen/cheatsheet.py | 13 +++++++++---- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/bot/constants.py b/bot/constants.py index 1d41a53e80..23865272b4 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -104,12 +104,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 @@ -128,6 +122,10 @@ class Channels(NamedTuple): voice_chat_1 = 799647045886541885 +class Categories(NamedTuple): + help_in_use = 696958401460043776 + + class Client(NamedTuple): name = "Sir Lancebot" guild = int(environ.get("BOT_GUILD", 267624335836053506)) @@ -249,6 +247,7 @@ class Roles(NamedTuple): rockstars = 458226413825294336 core_developers = 587606783669829632 events_lead = 778361735739998228 + everyone = 267624335836053506 class Tokens(NamedTuple): diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py index c83af839d0..83098c7631 100644 --- a/bot/exts/evergreen/cheatsheet.py +++ b/bot/exts/evergreen/cheatsheet.py @@ -3,13 +3,13 @@ import typing as t from urllib.parse import quote_plus -from discord import Embed +from discord import Embed, utils from discord.ext import commands from discord.ext.commands import BucketType, Context from bot import constants -from bot.constants import Channels, Colours, ERROR_REPLIES, WHITELISTED_CHANNELS -from bot.utils.decorators import override_in_channel +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. @@ -72,8 +72,8 @@ def result_fmt(self, url: str, body_text: str) -> t.Tuple[bool, t.Union[str, Emb name="cheat", aliases=("cht.sh", "cheatsheet", "cheat-sheet", "cht"), ) - @override_in_channel(WHITELISTED_CHANNELS) @commands.cooldown(1, 10, BucketType.user) + @with_role(Roles.everyone) async def cheat_sheet(self, ctx: Context, *search_terms: str) -> None: """ Search cheat.sh. @@ -82,6 +82,11 @@ async def cheat_sheet(self, ctx: Context, *search_terms: str) -> None: Usage: --> .cht read json """ + category = utils.get(ctx.message.guild.categories, id=Categories.help_in_use) + all_allowed_channels = WHITELISTED_CHANNELS + tuple(category.channels) + if ctx.channel not in all_allowed_channels: + return + async with self.bot.http_session.get( URL.format(search=quote_plus(" ".join(search_terms))) ) as response: From b10b2524a1284f7462f3b0f039827e6d115e7931 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Tue, 2 Feb 2021 06:16:38 +0530 Subject: [PATCH 06/11] Improve category check code --- bot/exts/evergreen/cheatsheet.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py index 83098c7631..abc5306b42 100644 --- a/bot/exts/evergreen/cheatsheet.py +++ b/bot/exts/evergreen/cheatsheet.py @@ -3,7 +3,7 @@ import typing as t from urllib.parse import quote_plus -from discord import Embed, utils +from discord import Embed from discord.ext import commands from discord.ext.commands import BucketType, Context @@ -82,9 +82,10 @@ async def cheat_sheet(self, ctx: Context, *search_terms: str) -> None: Usage: --> .cht read json """ - category = utils.get(ctx.message.guild.categories, id=Categories.help_in_use) - all_allowed_channels = WHITELISTED_CHANNELS + tuple(category.channels) - if ctx.channel not in all_allowed_channels: + if not ( + ctx.channel.category.id == Categories.help_in_use + or ctx.channel.id in WHITELISTED_CHANNELS + ): return async with self.bot.http_session.get( From 5190f5b8576267807dd6a4920964d684f0d572a4 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Tue, 2 Feb 2021 06:17:58 +0530 Subject: [PATCH 07/11] everyone -> everyone_role and remove developers role --- bot/constants.py | 3 +-- bot/exts/evergreen/cheatsheet.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/bot/constants.py b/bot/constants.py index 23865272b4..8e210ad312 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -236,7 +236,6 @@ class Roles(NamedTuple): announcements = 463658397560995840 champion = 430492892331769857 contributor = 295488872404484098 - developer = 352427296948486144 devops = 409416496733880320 jammer = 423054537079783434 moderator = 267629731250176001 @@ -247,7 +246,7 @@ class Roles(NamedTuple): rockstars = 458226413825294336 core_developers = 587606783669829632 events_lead = 778361735739998228 - everyone = 267624335836053506 + everyone_role = 267624335836053506 class Tokens(NamedTuple): diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py index abc5306b42..f650e3b0bd 100644 --- a/bot/exts/evergreen/cheatsheet.py +++ b/bot/exts/evergreen/cheatsheet.py @@ -73,7 +73,7 @@ def result_fmt(self, url: str, body_text: str) -> t.Tuple[bool, t.Union[str, Emb aliases=("cht.sh", "cheatsheet", "cheat-sheet", "cht"), ) @commands.cooldown(1, 10, BucketType.user) - @with_role(Roles.everyone) + @with_role(Roles.everyone_role) async def cheat_sheet(self, ctx: Context, *search_terms: str) -> None: """ Search cheat.sh. From 3d30a1ff9103fc59bd7fcc0ec8b1e7304beb08d4 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Fri, 5 Feb 2021 09:27:25 +0530 Subject: [PATCH 08/11] Abrupt response, so make the bot type --- bot/exts/evergreen/cheatsheet.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py index f650e3b0bd..b3ee0b948a 100644 --- a/bot/exts/evergreen/cheatsheet.py +++ b/bot/exts/evergreen/cheatsheet.py @@ -88,19 +88,20 @@ async def cheat_sheet(self, ctx: Context, *search_terms: str) -> None: ): return - async with self.bot.http_session.get( - URL.format(search=quote_plus(" ".join(search_terms))) - ) as response: - result = ANSI_RE.sub("", await response.text()).translate(ESCAPE_TT) - - is_embed, description = self.result_fmt( - URL.format(search=quote_plus(" ".join(search_terms))), - result - ) - if is_embed: - await ctx.send(embed=description) - else: - await ctx.send(content=description) + async with ctx.typing(): + async with self.bot.http_session.get( + URL.format(search=quote_plus(" ".join(search_terms))) + ) as response: + result = ANSI_RE.sub("", await response.text()).translate(ESCAPE_TT) + + is_embed, description = self.result_fmt( + URL.format(search=quote_plus(" ".join(search_terms))), + result + ) + if is_embed: + await ctx.send(embed=description) + else: + await ctx.send(content=description) def setup(bot: commands.Bot) -> None: From f6cccfe73321173d24667321b41f2e2b05f29aac Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Fri, 5 Feb 2021 09:28:28 +0530 Subject: [PATCH 09/11] Move repeated code to a single variable --- bot/exts/evergreen/cheatsheet.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py index b3ee0b948a..acd77e590c 100644 --- a/bot/exts/evergreen/cheatsheet.py +++ b/bot/exts/evergreen/cheatsheet.py @@ -89,13 +89,15 @@ async def cheat_sheet(self, ctx: Context, *search_terms: str) -> None: return async with ctx.typing(): + search_string = quote_plus(" ".join(search_terms)) + async with self.bot.http_session.get( - URL.format(search=quote_plus(" ".join(search_terms))) + URL.format(search=search_string) ) as response: result = ANSI_RE.sub("", await response.text()).translate(ESCAPE_TT) is_embed, description = self.result_fmt( - URL.format(search=quote_plus(" ".join(search_terms))), + URL.format(search=search_string), result ) if is_embed: From 95950b93f5e01819921f9bc32a1613bdf1ddd13b Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Fri, 5 Feb 2021 09:30:10 +0530 Subject: [PATCH 10/11] Use brackets instead of / for multi line strings --- bot/exts/evergreen/cheatsheet.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py index acd77e590c..dd44c68e79 100644 --- a/bot/exts/evergreen/cheatsheet.py +++ b/bot/exts/evergreen/cheatsheet.py @@ -58,14 +58,14 @@ def result_fmt(self, url: str, body_text: str) -> t.Tuple[bool, t.Union[str, Emb 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} " + 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}" + description = (f"**Result Of cht.sh**\n" + f"```python\n{body_text}```\n" + f"{url}") return False, description @commands.command( From 23c0b2f9464b993c8f2fd33dc2941bef8b0a9851 Mon Sep 17 00:00:00 2001 From: Shivansh-007 Date: Fri, 5 Feb 2021 09:31:09 +0530 Subject: [PATCH 11/11] Fix indentation --- bot/exts/evergreen/cheatsheet.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bot/exts/evergreen/cheatsheet.py b/bot/exts/evergreen/cheatsheet.py index dd44c68e79..9748536555 100644 --- a/bot/exts/evergreen/cheatsheet.py +++ b/bot/exts/evergreen/cheatsheet.py @@ -59,13 +59,13 @@ def result_fmt(self, url: str, body_text: str) -> t.Tuple[bool, t.Union[str, Emb 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} ") + 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}") + f"```python\n{body_text}```\n" + f"{url}") return False, description @commands.command( @@ -83,8 +83,8 @@ async def cheat_sheet(self, ctx: Context, *search_terms: str) -> None: --> .cht read json """ if not ( - ctx.channel.category.id == Categories.help_in_use - or ctx.channel.id in WHITELISTED_CHANNELS + ctx.channel.category.id == Categories.help_in_use + or ctx.channel.id in WHITELISTED_CHANNELS ): return