aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Shivansh-007 <[email protected]>2021-01-23 17:39:51 +0530
committerGravatar Shivansh-007 <[email protected]>2021-01-23 17:39:51 +0530
commit9b62d84554fe8a27e3baef5e73eaac9127b2e54d (patch)
tree4f1a0ae70a4d0c64de4363c243c3cc5cf7190cdf
parentUpdate the README badges (diff)
Add ability to automatically send issues if matching <repo>#<issue>
-rw-r--r--bot/exts/evergreen/issues.py96
1 files changed, 69 insertions, 27 deletions
diff --git a/bot/exts/evergreen/issues.py b/bot/exts/evergreen/issues.py
index e419a6f5..b701346c 100644
--- a/bot/exts/evergreen/issues.py
+++ b/bot/exts/evergreen/issues.py
@@ -1,5 +1,7 @@
import logging
import random
+import re
+import typing as t
import discord
from discord.ext import commands
@@ -13,9 +15,7 @@ BAD_RESPONSE = {
404: "Issue/pull request not located! Please enter a valid number!",
403: "Rate limit has been hit! Please try again later!"
}
-
MAX_REQUESTS = 10
-
REQUEST_HEADERS = dict()
if GITHUB_TOKEN := Tokens.github:
REQUEST_HEADERS["Authorization"] = f"token {GITHUB_TOKEN}"
@@ -27,31 +27,19 @@ class Issues(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
- @commands.command(aliases=("pr",))
- @override_in_channel(WHITELISTED_CHANNELS + (Channels.dev_contrib, Channels.dev_branding))
- async def issue(
- self,
- ctx: commands.Context,
- numbers: commands.Greedy[int],
- repository: str = "sir-lancebot",
- user: str = "python-discord"
- ) -> None:
- """Command to retrieve issue(s) from a GitHub repository."""
+ async def fetch_issues(
+ self,
+ numbers: set,
+ repository: str,
+ user: str
+ ) -> t.Union[str, list]:
+ """Retrieve issue(s) from a GitHub repository."""
links = []
- numbers = set(numbers) # Convert from list to set to remove duplicates, if any
-
if not numbers:
- await ctx.invoke(self.bot.get_command('help'), 'issue')
- return
+ return "Numbers not found."
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
+ return "Max requests hit."
for number in numbers:
url = f"https://api.github.com/repos/{user}/{repository}/issues/{number}"
@@ -63,7 +51,7 @@ class Issues(commands.Cog):
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)}")
+ return 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
@@ -92,15 +80,69 @@ 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]
+ return links
+
+ @staticmethod
+ def get_embed(result: list, user: str = "python-discord", repository: str = "") -> discord.Embed:
+ """Get Response Embed."""
+ description_list = ["{0} [{1}]({2})".format(*link) for link in result]
resp = discord.Embed(
colour=Colours.bright_green,
description='\n'.join(description_list)
)
resp.set_author(name="GitHub", url=f"https://github.com/{user}/{repository}")
- await ctx.send(embed=resp)
+ return resp
+
+ @commands.command(aliases=("pr",))
+ @override_in_channel(WHITELISTED_CHANNELS + (Channels.dev_contrib, Channels.dev_branding))
+ async def issue(
+ self,
+ ctx: commands.Context,
+ numbers: commands.Greedy[int],
+ repository: str = "sir-lancebot",
+ user: str = "python-discord"
+ ) -> None:
+ """Command to retrieve issue(s) from a GitHub repository."""
+ print(numbers)
+ result = await self.fetch_issues(set(numbers), repository, user)
+
+ if result == "Numbers not found.":
+ await ctx.invoke(self.bot.get_command('help'), 'issue')
+
+ elif result == "Max requests hit.":
+ 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)
+
+ elif isinstance(result, list):
+ # Issue/PR format: emoji to show if open/closed/merged, number and the title as a singular link.
+ resp = self.get_embed(result, user, repository)
+ await ctx.send(embed=resp)
+
+ elif isinstance(result, str):
+ await ctx.send(result)
+
+ @commands.Cog.listener()
+ async def on_message(self, message: discord.Message) -> None:
+ """Command to retrieve issue(s) from a GitHub repository using automatic linking if matching <repo>#<issue>."""
+ message_repo_issue_map = re.findall(r".+?(bot|meta|sir-lancebot|logcord)#(\d+)", message.content)
+ links = []
+
+ if message_repo_issue_map:
+ for repo_issue in message_repo_issue_map:
+ result = await self.fetch_issues({repo_issue[1]}, repo_issue[0], "python-discord")
+ if isinstance(result, list):
+ links.append(*result)
+
+ if not links:
+ return
+
+ resp = self.get_embed(links, "python-discord")
+ await message.channel.send(embed=resp)
def setup(bot: commands.Bot) -> None: