diff options
Diffstat (limited to 'bot/seasons/evergreen/issues.py')
| -rw-r--r-- | bot/seasons/evergreen/issues.py | 73 | 
1 files changed, 47 insertions, 26 deletions
| diff --git a/bot/seasons/evergreen/issues.py b/bot/seasons/evergreen/issues.py index 438ab475..c7501a5d 100644 --- a/bot/seasons/evergreen/issues.py +++ b/bot/seasons/evergreen/issues.py @@ -3,10 +3,16 @@ import logging  import discord  from discord.ext import commands -from bot.constants import Colours +from bot.constants import Channels, Colours, Emojis, WHITELISTED_CHANNELS  from bot.decorators import override_in_channel  log = logging.getLogger(__name__) +ISSUE_WHITELIST = WHITELISTED_CHANNELS + (Channels.seasonalbot_chat,) + +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): @@ -15,43 +21,58 @@ class Issues(commands.Cog):      def __init__(self, bot: commands.Bot):          self.bot = bot -    @commands.command(aliases=("issues",)) -    @override_in_channel() +    @commands.command(aliases=("pr",)) +    @override_in_channel(ISSUE_WHITELIST)      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.""" -        api_url = f"https://api.github.com/repos/{user}/{repository}/issues/{number}" -        failed_status = { -            404: f"Issue #{number} doesn't exist in the repository {user}/{repository}.", -            403: f"Rate limit exceeded. Please wait a while before trying again!" -        } +        url = f"https://api.github.com/repos/{user}/{repository}/issues/{number}" +        merge_url = f"https://api.github.com/repos/{user}/{repository}/pulls/{number}/merge" -        async with self.bot.http_session.get(api_url) as r: +        log.trace(f"Querying GH issues API: {url}") +        async with self.bot.http_session.get(url) as r:              json_data = await r.json() -            response_code = r.status - -        if response_code in failed_status: -            return await ctx.send(failed_status[response_code]) -        repo_url = f"https://github.com/{user}/{repository}" -        issue_embed = discord.Embed(colour=Colours.bright_green) -        issue_embed.add_field(name="Repository", value=f"[{user}/{repository}]({repo_url})", inline=False) -        issue_embed.add_field(name="Issue Number", value=f"#{number}", inline=False) -        issue_embed.add_field(name="Status", value=json_data["state"].title()) -        issue_embed.add_field(name="Link", value=json_data["html_url"], inline=False) +        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)}") -        description = json_data["body"] -        if len(description) > 1024: -            placeholder = " [...]" -            description = f"{description[:1024 - len(placeholder)]}{placeholder}" +        # 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 -        issue_embed.add_field(name="Description", value=description, inline=False) +        # 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 -        await ctx.send(embed=issue_embed) +        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: -    """Github Issues Cog Load.""" +    """Cog Retrieves Issues From Github."""      bot.add_cog(Issues(bot))      log.info("Issues cog loaded") | 
