From 0da256ca8986700e9c288f26b9db9c8e0f842465 Mon Sep 17 00:00:00 2001 From: brad90four <42116429+brad90four@users.noreply.github.com> Date: Sat, 28 Aug 2021 08:37:48 -0400 Subject: Add a Real Python search command (#805) Co-authored-by: Vthechamp22 Co-authored-by: Bluenix --- bot/exts/evergreen/realpython.py | 76 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 bot/exts/evergreen/realpython.py (limited to 'bot/exts/evergreen/realpython.py') diff --git a/bot/exts/evergreen/realpython.py b/bot/exts/evergreen/realpython.py new file mode 100644 index 00000000..e722dd4b --- /dev/null +++ b/bot/exts/evergreen/realpython.py @@ -0,0 +1,76 @@ +import logging +from html import unescape +from urllib.parse import quote_plus + +from discord import Embed +from discord.ext import commands + +from bot import bot +from bot.constants import Colours + +logger = logging.getLogger(__name__) + + +API_ROOT = "https://realpython.com/search/api/v1/" +ARTICLE_URL = "https://realpython.com{article_url}" +SEARCH_URL = "https://realpython.com/search?q={user_search}" + + +ERROR_EMBED = Embed( + title="Error while searching Real Python", + description="There was an error while trying to reach Real Python. Please try again shortly.", + color=Colours.soft_red, +) + + +class RealPython(commands.Cog): + """User initiated command to search for a Real Python article.""" + + def __init__(self, bot: bot.Bot): + self.bot = bot + + @commands.command(aliases=["rp"]) + @commands.cooldown(1, 10, commands.cooldowns.BucketType.user) + async def realpython(self, ctx: commands.Context, *, user_search: str) -> None: + """Send 5 articles that match the user's search terms.""" + params = {"q": user_search, "limit": 5} + async with self.bot.http_session.get(url=API_ROOT, params=params) as response: + if response.status != 200: + logger.error( + f"Unexpected status code {response.status} from Real Python" + ) + await ctx.send(embed=ERROR_EMBED) + return + + data = await response.json() + + articles = data["results"] + + if len(articles) == 0: + no_articles = Embed( + title=f"No articles found for '{user_search}'", color=Colours.soft_red + ) + await ctx.send(embed=no_articles) + return + + article_embed = Embed( + title="Search results - Real Python", + url=SEARCH_URL.format(user_search=quote_plus(user_search)), + description="Here are the top 5 results:", + color=Colours.orange, + ) + + for article in articles: + article_embed.add_field( + name=unescape(article["title"]), + value=ARTICLE_URL.format(article_url=article["url"]), + inline=False, + ) + article_embed.set_footer(text="Click the links to go to the articles.") + + await ctx.send(embed=article_embed) + + +def setup(bot: bot.Bot) -> None: + """Load the Real Python Cog.""" + bot.add_cog(RealPython(bot)) -- cgit v1.2.3 From 397605b14ecb0262d3dfa904a1661eb2514a1d5e Mon Sep 17 00:00:00 2001 From: brad90four <42116429+brad90four@users.noreply.github.com> Date: Mon, 30 Aug 2021 12:13:29 -0400 Subject: Only send articles to user Added the "kind": "article" parameter to the API request. This should only return articles to the user instead of courses, lessons or quizzes. Also updated the "Here are the top x results" message to handle a variable amount of articles. [Ticket: python-discord#828] --- bot/exts/evergreen/realpython.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bot/exts/evergreen/realpython.py') diff --git a/bot/exts/evergreen/realpython.py b/bot/exts/evergreen/realpython.py index e722dd4b..6d148ad6 100644 --- a/bot/exts/evergreen/realpython.py +++ b/bot/exts/evergreen/realpython.py @@ -33,7 +33,7 @@ class RealPython(commands.Cog): @commands.cooldown(1, 10, commands.cooldowns.BucketType.user) async def realpython(self, ctx: commands.Context, *, user_search: str) -> None: """Send 5 articles that match the user's search terms.""" - params = {"q": user_search, "limit": 5} + params = {"q": user_search, "limit": 5, "kind": "article"} async with self.bot.http_session.get(url=API_ROOT, params=params) as response: if response.status != 200: logger.error( @@ -56,7 +56,7 @@ class RealPython(commands.Cog): article_embed = Embed( title="Search results - Real Python", url=SEARCH_URL.format(user_search=quote_plus(user_search)), - description="Here are the top 5 results:", + description=f"Here are the top {max(5, len(articles))} results:", color=Colours.orange, ) -- cgit v1.2.3 From 990dcf80b0813a85865450c9ad038d3ed620ec08 Mon Sep 17 00:00:00 2001 From: brad90four <42116429+brad90four@users.noreply.github.com> Date: Mon, 30 Aug 2021 12:37:26 -0400 Subject: Correct article length check with future proofing Co-authored-by: wookie184 --- bot/exts/evergreen/realpython.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot/exts/evergreen/realpython.py') diff --git a/bot/exts/evergreen/realpython.py b/bot/exts/evergreen/realpython.py index 6d148ad6..6ef750a9 100644 --- a/bot/exts/evergreen/realpython.py +++ b/bot/exts/evergreen/realpython.py @@ -56,7 +56,7 @@ class RealPython(commands.Cog): article_embed = Embed( title="Search results - Real Python", url=SEARCH_URL.format(user_search=quote_plus(user_search)), - description=f"Here are the top {max(5, len(articles))} results:", + description=f"Here are the top {len(articles)} results:", color=Colours.orange, ) -- cgit v1.2.3 From 0f63eea5090574123359e84b1ada0efd767cd0c8 Mon Sep 17 00:00:00 2001 From: brad90four <42116429+brad90four@users.noreply.github.com> Date: Mon, 30 Aug 2021 14:48:30 -0400 Subject: Handle single article result --- bot/exts/evergreen/realpython.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'bot/exts/evergreen/realpython.py') diff --git a/bot/exts/evergreen/realpython.py b/bot/exts/evergreen/realpython.py index 6ef750a9..5d9e5c5c 100644 --- a/bot/exts/evergreen/realpython.py +++ b/bot/exts/evergreen/realpython.py @@ -53,10 +53,15 @@ class RealPython(commands.Cog): await ctx.send(embed=no_articles) return + if len(articles) == 1: + article_description = "Here is the result:" + else: + article_description = f"Here are the top {len(articles)} results:" + article_embed = Embed( title="Search results - Real Python", url=SEARCH_URL.format(user_search=quote_plus(user_search)), - description=f"Here are the top {len(articles)} results:", + description=article_description, color=Colours.orange, ) -- cgit v1.2.3