From a13f5737cdd947ac297f7af790d0c614aab0474a Mon Sep 17 00:00:00 2001 From: Xithrius Date: Sat, 19 Sep 2020 14:52:54 -0700 Subject: Updated issue/pr command to get multiple links. --- bot/exts/evergreen/issues.py | 84 ++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 38 deletions(-) (limited to 'bot/exts/evergreen/issues.py') diff --git a/bot/exts/evergreen/issues.py b/bot/exts/evergreen/issues.py index 0f83731b..58ffe408 100644 --- a/bot/exts/evergreen/issues.py +++ b/bot/exts/evergreen/issues.py @@ -23,51 +23,59 @@ class Issues(commands.Cog): @commands.command(aliases=("pr",)) @override_in_channel(WHITELISTED_CHANNELS + (Channels.dev_contrib,)) async def issue( - self, ctx: commands.Context, number: int, repository: str = "seasonalbot", user: str = "python-discord" + self, ctx: commands.Context, numbers: commands.Greedy[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: + """Command to retrieve issue(s) from a GitHub repository.""" + links = [] + + for number in set(numbers): + # Convert from list to set to remove duplicates, if any. + 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)}] #{number} {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.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 + icon_url = Emojis.issue else: - icon_url = Emojis.pull_request_closed + icon_url = Emojis.issue_closed - issue_url = json_data.get("html_url") - description_text = f"[{repository}] #{number} {json_data.get('title')}" + # 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") + links.append([icon_url, f"[{repository}] #{number} {json_data.get('title')}", issue_url]) + + description_list = ['{0} [{1}]({2})'.format(*link) for link in links] resp = discord.Embed( colour=Colours.bright_green, - description=f"{icon_url} [{description_text}]({issue_url})" + description='\n'.join(description_list) ) - resp.set_author(name="GitHub", url=issue_url) + + resp.set_author(name="GitHub", url=f"https://github.com/python-discord/{repository}") await ctx.send(embed=resp) -- cgit v1.2.3 From 7a29cce2d06303965a89b789b352d4a5d9637f28 Mon Sep 17 00:00:00 2001 From: Xithrius Date: Sat, 19 Sep 2020 15:06:24 -0700 Subject: Replaced single quotes with double, set the repo link to be user-defined --- bot/exts/evergreen/issues.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bot/exts/evergreen/issues.py') diff --git a/bot/exts/evergreen/issues.py b/bot/exts/evergreen/issues.py index 58ffe408..2f086f59 100644 --- a/bot/exts/evergreen/issues.py +++ b/bot/exts/evergreen/issues.py @@ -69,13 +69,13 @@ class Issues(commands.Cog): issue_url = json_data.get("html_url") links.append([icon_url, f"[{repository}] #{number} {json_data.get('title')}", issue_url]) - description_list = ['{0} [{1}]({2})'.format(*link) for link in links] + description_list = ["{0} [{1}]({2})".format(*link) for link in links] resp = discord.Embed( colour=Colours.bright_green, description='\n'.join(description_list) ) - resp.set_author(name="GitHub", url=f"https://github.com/python-discord/{repository}") + resp.set_author(name="GitHub", url=f"https://github.com/{user}/{repository}") await ctx.send(embed=resp) -- cgit v1.2.3 From 733a634784d848fd3b6a1c575aa7d3a0f8be44c9 Mon Sep 17 00:00:00 2001 From: Xithrius Date: Sat, 19 Sep 2020 15:08:11 -0700 Subject: Described how links are shown in the embed. --- bot/exts/evergreen/issues.py | 1 + 1 file changed, 1 insertion(+) (limited to 'bot/exts/evergreen/issues.py') diff --git a/bot/exts/evergreen/issues.py b/bot/exts/evergreen/issues.py index 2f086f59..d909ae6e 100644 --- a/bot/exts/evergreen/issues.py +++ b/bot/exts/evergreen/issues.py @@ -69,6 +69,7 @@ class Issues(commands.Cog): issue_url = json_data.get("html_url") links.append([icon_url, f"[{repository}] #{number} {json_data.get('title')}", issue_url]) + # Issue/PR format: emoji to show if open/closed/merged, number and the title as a singular link. description_list = ["{0} [{1}]({2})".format(*link) for link in links] resp = discord.Embed( colour=Colours.bright_green, -- cgit v1.2.3 From 24b788d11bec461718b540d5d9fec2785afa5d23 Mon Sep 17 00:00:00 2001 From: Den4200 Date: Sat, 19 Sep 2020 20:31:26 -0400 Subject: Allow `issue` command in #dev-branding --- bot/constants.py | 1 + bot/exts/evergreen/issues.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'bot/exts/evergreen/issues.py') diff --git a/bot/constants.py b/bot/constants.py index 6605882d..fa428a61 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -52,6 +52,7 @@ class Channels(NamedTuple): devalerts = 460181980097675264 devlog = int(environ.get("CHANNEL_DEVLOG", 622895325144940554)) dev_contrib = 635950537262759947 + dev_branding = 753252897059373066 help_0 = 303906576991780866 help_1 = 303906556754395136 help_2 = 303906514266226689 diff --git a/bot/exts/evergreen/issues.py b/bot/exts/evergreen/issues.py index d909ae6e..97baac6a 100644 --- a/bot/exts/evergreen/issues.py +++ b/bot/exts/evergreen/issues.py @@ -21,9 +21,12 @@ class Issues(commands.Cog): self.bot = bot @commands.command(aliases=("pr",)) - @override_in_channel(WHITELISTED_CHANNELS + (Channels.dev_contrib,)) + @override_in_channel(WHITELISTED_CHANNELS + (Channels.dev_contrib, Channels.dev_branding)) async def issue( - self, ctx: commands.Context, numbers: commands.Greedy[int], repository: str = "seasonalbot", + self, + ctx: commands.Context, + numbers: commands.Greedy[int], + repository: str = "seasonalbot", user: str = "python-discord" ) -> None: """Command to retrieve issue(s) from a GitHub repository.""" -- cgit v1.2.3 From 91ca04e823eff28907f4018b851bf78a1ffb085e Mon Sep 17 00:00:00 2001 From: Den4200 Date: Sat, 19 Sep 2020 20:36:54 -0400 Subject: Limit maximum PRs/issues to 10 per invocation --- bot/exts/evergreen/issues.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'bot/exts/evergreen/issues.py') diff --git a/bot/exts/evergreen/issues.py b/bot/exts/evergreen/issues.py index 97baac6a..2a9359b7 100644 --- a/bot/exts/evergreen/issues.py +++ b/bot/exts/evergreen/issues.py @@ -1,9 +1,10 @@ import logging +import random import discord from discord.ext import commands -from bot.constants import Channels, Colours, Emojis, WHITELISTED_CHANNELS +from bot.constants import Channels, Colours, Emojis, ERROR_REPLIES, WHITELISTED_CHANNELS from bot.utils.decorators import override_in_channel log = logging.getLogger(__name__) @@ -13,6 +14,8 @@ BAD_RESPONSE = { 403: "Rate limit has been hit! Please try again later!" } +MAX_REQUESTS = 10 + class Issues(commands.Cog): """Cog that allows users to retrieve issues from GitHub.""" @@ -31,6 +34,16 @@ class Issues(commands.Cog): ) -> None: """Command to retrieve issue(s) from a GitHub repository.""" links = [] + numbers = set(numbers) + + if len(numbers) > MAX_REQUESTS: + embed = discord.Embed( + title=random.choice(ERROR_REPLIES), + color=Colours.soft_red, + description=f"Too many issues/PRs! (maximum of {MAX_REQUESTS})" + ) + await ctx.send(embed=embed) + return for number in set(numbers): # Convert from list to set to remove duplicates, if any. -- cgit v1.2.3 From d777222ccfad97f17a44b1deb342e5e89bca9946 Mon Sep 17 00:00:00 2001 From: Den4200 Date: Sat, 19 Sep 2020 20:37:36 -0400 Subject: Invoke help command when no PRs/issues are given --- bot/exts/evergreen/issues.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'bot/exts/evergreen/issues.py') diff --git a/bot/exts/evergreen/issues.py b/bot/exts/evergreen/issues.py index 2a9359b7..e128ae50 100644 --- a/bot/exts/evergreen/issues.py +++ b/bot/exts/evergreen/issues.py @@ -36,6 +36,10 @@ class Issues(commands.Cog): links = [] numbers = set(numbers) + if not numbers: + await ctx.invoke(self.bot.get_command('help'), 'issue') + return + if len(numbers) > MAX_REQUESTS: embed = discord.Embed( title=random.choice(ERROR_REPLIES), -- cgit v1.2.3 From 157cc184c075287eb24a765b15430f2530d44bae Mon Sep 17 00:00:00 2001 From: Den4200 Date: Sat, 19 Sep 2020 20:38:30 -0400 Subject: Authenticate with the GitHub API to allow for more requests --- bot/exts/evergreen/issues.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'bot/exts/evergreen/issues.py') diff --git a/bot/exts/evergreen/issues.py b/bot/exts/evergreen/issues.py index e128ae50..15c97473 100644 --- a/bot/exts/evergreen/issues.py +++ b/bot/exts/evergreen/issues.py @@ -4,7 +4,7 @@ import random import discord from discord.ext import commands -from bot.constants import Channels, Colours, Emojis, ERROR_REPLIES, WHITELISTED_CHANNELS +from bot.constants import Channels, Colours, Emojis, ERROR_REPLIES, Tokens, WHITELISTED_CHANNELS from bot.utils.decorators import override_in_channel log = logging.getLogger(__name__) @@ -16,6 +16,10 @@ BAD_RESPONSE = { MAX_REQUESTS = 10 +REQUEST_HEADERS = dict() +if GITHUB_TOKEN := Tokens.github: + REQUEST_HEADERS["Authorization"] = f"token {GITHUB_TOKEN}" + class Issues(commands.Cog): """Cog that allows users to retrieve issues from GitHub.""" @@ -30,7 +34,7 @@ class Issues(commands.Cog): ctx: commands.Context, numbers: commands.Greedy[int], repository: str = "seasonalbot", - user: str = "python-discord" + user: str = "python-discord" ) -> None: """Command to retrieve issue(s) from a GitHub repository.""" links = [] @@ -55,7 +59,7 @@ class Issues(commands.Cog): 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: + async with self.bot.http_session.get(url, headers=REQUEST_HEADERS) as r: json_data = await r.json() if r.status in BAD_RESPONSE: -- cgit v1.2.3 From fc5837770a0a1b49986768455a36d82193fbaadd Mon Sep 17 00:00:00 2001 From: Den4200 Date: Sat, 19 Sep 2020 20:48:12 -0400 Subject: Fix order of imports --- bot/exts/evergreen/issues.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot/exts/evergreen/issues.py') diff --git a/bot/exts/evergreen/issues.py b/bot/exts/evergreen/issues.py index 15c97473..5a5c82e7 100644 --- a/bot/exts/evergreen/issues.py +++ b/bot/exts/evergreen/issues.py @@ -4,7 +4,7 @@ import random import discord from discord.ext import commands -from bot.constants import Channels, Colours, Emojis, ERROR_REPLIES, Tokens, WHITELISTED_CHANNELS +from bot.constants import Channels, Colours, ERROR_REPLIES, Emojis, Tokens, WHITELISTED_CHANNELS from bot.utils.decorators import override_in_channel log = logging.getLogger(__name__) -- cgit v1.2.3