aboutsummaryrefslogtreecommitdiffstats
path: root/bot/exts/utilities/stackoverflow.py
diff options
context:
space:
mode:
authorGravatar Janine vN <[email protected]>2021-09-05 00:12:47 -0400
committerGravatar Janine vN <[email protected]>2021-09-05 00:12:47 -0400
commit66c888ad68ad88ba1d39c2ac4824469560b8c29a (patch)
tree706917000c39c3af1fc92c47fd59fe31a63f601a /bot/exts/utilities/stackoverflow.py
parentMove internal eval and rename utils to core (diff)
Move practical functions into utilities folder
Separates out the useful/practical seasonal bot features from the evergreen folder into a "utilities" folder. Adjusts the paths to resources to reflect the folder move.
Diffstat (limited to 'bot/exts/utilities/stackoverflow.py')
-rw-r--r--bot/exts/utilities/stackoverflow.py88
1 files changed, 88 insertions, 0 deletions
diff --git a/bot/exts/utilities/stackoverflow.py b/bot/exts/utilities/stackoverflow.py
new file mode 100644
index 00000000..64455e33
--- /dev/null
+++ b/bot/exts/utilities/stackoverflow.py
@@ -0,0 +1,88 @@
+import logging
+from html import unescape
+from urllib.parse import quote_plus
+
+from discord import Embed, HTTPException
+from discord.ext import commands
+
+from bot.bot import Bot
+from bot.constants import Colours, Emojis
+
+logger = logging.getLogger(__name__)
+
+BASE_URL = "https://api.stackexchange.com/2.2/search/advanced"
+SO_PARAMS = {
+ "order": "desc",
+ "sort": "activity",
+ "site": "stackoverflow"
+}
+SEARCH_URL = "https://stackoverflow.com/search?q={query}"
+ERR_EMBED = Embed(
+ title="Error in fetching results from Stackoverflow",
+ description=(
+ "Sorry, there was en error while trying to fetch data from the Stackoverflow website. Please try again in some "
+ "time. If this issue persists, please contact the staff or send a message in #dev-contrib."
+ ),
+ color=Colours.soft_red
+)
+
+
+class Stackoverflow(commands.Cog):
+ """Contains command to interact with stackoverflow from discord."""
+
+ def __init__(self, bot: Bot):
+ self.bot = bot
+
+ @commands.command(aliases=["so"])
+ @commands.cooldown(1, 15, commands.cooldowns.BucketType.user)
+ async def stackoverflow(self, ctx: commands.Context, *, search_query: str) -> None:
+ """Sends the top 5 results of a search query from stackoverflow."""
+ params = SO_PARAMS | {"q": search_query}
+ async with self.bot.http_session.get(url=BASE_URL, params=params) as response:
+ if response.status == 200:
+ data = await response.json()
+ else:
+ logger.error(f'Status code is not 200, it is {response.status}')
+ await ctx.send(embed=ERR_EMBED)
+ return
+ if not data['items']:
+ no_search_result = Embed(
+ title=f"No search results found for {search_query}",
+ color=Colours.soft_red
+ )
+ await ctx.send(embed=no_search_result)
+ return
+
+ top5 = data["items"][:5]
+ encoded_search_query = quote_plus(search_query)
+ embed = Embed(
+ title="Search results - Stackoverflow",
+ url=SEARCH_URL.format(query=encoded_search_query),
+ description=f"Here are the top {len(top5)} results:",
+ color=Colours.orange
+ )
+ for item in top5:
+ embed.add_field(
+ name=unescape(item['title']),
+ value=(
+ f"[{Emojis.reddit_upvote} {item['score']} "
+ f"{Emojis.stackoverflow_views} {item['view_count']} "
+ f"{Emojis.reddit_comments} {item['answer_count']} "
+ f"{Emojis.stackoverflow_tag} {', '.join(item['tags'][:3])}]"
+ f"({item['link']})"
+ ),
+ inline=False)
+ embed.set_footer(text="View the original link for more results.")
+ try:
+ await ctx.send(embed=embed)
+ except HTTPException:
+ search_query_too_long = Embed(
+ title="Your search query is too long, please try shortening your search query",
+ color=Colours.soft_red
+ )
+ await ctx.send(embed=search_query_too_long)
+
+
+def setup(bot: Bot) -> None:
+ """Load the Stackoverflow Cog."""
+ bot.add_cog(Stackoverflow(bot))