aboutsummaryrefslogtreecommitdiffstats
path: root/bot/exts/evergreen/issues.py
diff options
context:
space:
mode:
Diffstat (limited to 'bot/exts/evergreen/issues.py')
-rw-r--r--bot/exts/evergreen/issues.py77
1 files changed, 77 insertions, 0 deletions
diff --git a/bot/exts/evergreen/issues.py b/bot/exts/evergreen/issues.py
new file mode 100644
index 00000000..fb18b62a
--- /dev/null
+++ b/bot/exts/evergreen/issues.py
@@ -0,0 +1,77 @@
+import logging
+
+import discord
+from discord.ext import commands
+
+from bot.constants import Colours, Emojis, WHITELISTED_CHANNELS
+from bot.utils.decorators import override_in_channel
+
+log = logging.getLogger(__name__)
+
+BAD_RESPONSE = {
+ 404: "Issue/pull request not located! Please enter a valid number!",
+ 403: "Rate limit has been hit! Please try again later!"
+}
+
+
+class Issues(commands.Cog):
+ """Cog that allows users to retrieve issues from GitHub."""
+
+ def __init__(self, bot: commands.Bot):
+ self.bot = bot
+
+ @commands.command(aliases=("pr",))
+ @override_in_channel(WHITELISTED_CHANNELS)
+ async def issue(
+ self, ctx: commands.Context, number: int, repository: str = "seasonalbot", user: str = "python-discord"
+ ) -> None:
+ """Command to retrieve issues from a GitHub repository."""
+ url = f"https://api.github.com/repos/{user}/{repository}/issues/{number}"
+ merge_url = f"https://api.github.com/repos/{user}/{repository}/pulls/{number}/merge"
+
+ log.trace(f"Querying GH issues API: {url}")
+ async with self.bot.http_session.get(url) as r:
+ json_data = await r.json()
+
+ if r.status in BAD_RESPONSE:
+ log.warning(f"Received response {r.status} from: {url}")
+ return await ctx.send(f"[{str(r.status)}] {BAD_RESPONSE.get(r.status)}")
+
+ # The initial API request is made to the issues API endpoint, which will return information
+ # if the issue or PR is present. However, the scope of information returned for PRs differs
+ # from issues: if the 'issues' key is present in the response then we can pull the data we
+ # need from the initial API call.
+ if "issues" in json_data.get("html_url"):
+ if json_data.get("state") == "open":
+ icon_url = Emojis.issue
+ else:
+ icon_url = Emojis.issue_closed
+
+ # If the 'issues' key is not contained in the API response and there is no error code, then
+ # we know that a PR has been requested and a call to the pulls API endpoint is necessary
+ # to get the desired information for the PR.
+ else:
+ log.trace(f"PR provided, querying GH pulls API for additional information: {merge_url}")
+ async with self.bot.http_session.get(merge_url) as m:
+ if json_data.get("state") == "open":
+ icon_url = Emojis.pull_request
+ # When the status is 204 this means that the state of the PR is merged
+ elif m.status == 204:
+ icon_url = Emojis.merge
+ else:
+ icon_url = Emojis.pull_request_closed
+
+ issue_url = json_data.get("html_url")
+ description_text = f"[{repository}] #{number} {json_data.get('title')}"
+ resp = discord.Embed(
+ colour=Colours.bright_green,
+ description=f"{icon_url} [{description_text}]({issue_url})"
+ )
+ resp.set_author(name="GitHub", url=issue_url)
+ await ctx.send(embed=resp)
+
+
+def setup(bot: commands.Bot) -> None:
+ """Cog Retrieves Issues From Github."""
+ bot.add_cog(Issues(bot))
+ log.info("Issues cog loaded")