Skip to content

Commit c7b8fcb

Browse files
authored
Add files via upload
1 parent ff8f7ec commit c7b8fcb

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

github/github.py

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import re
2+
import discord
3+
from discord.ext import commands
4+
5+
6+
class GithubPlugin(commands.Cog):
7+
def __init__(self, bot: commands.Bot):
8+
self.bot = bot
9+
self.colors = {
10+
"pr": {
11+
"open": 0x2CBE4E,
12+
"closed": None, # Use None instead of discord.Embed.Empty
13+
"merged": None, # Use None instead of discord.Embed.Empty
14+
},
15+
"issues": {
16+
"open": 0xE68D60,
17+
"closed": None, # Use None instead of discord.Embed.Empty
18+
},
19+
}
20+
self.regex = r"(\S+)#(\d+)" # Regex to match GitHub repo references
21+
22+
@commands.Cog.listener()
23+
async def on_message(self, msg: discord.Message):
24+
# Ignore bot messages
25+
if msg.author.bot:
26+
return
27+
28+
match = re.search(self.regex, msg.content)
29+
if not match:
30+
return
31+
32+
repo, num = match.groups()
33+
34+
# Map short repo names to full repo paths
35+
if repo == "modmail":
36+
repo = "modmail-dev/modmail"
37+
elif repo == "logviewer":
38+
repo = "modmail-dev/logviewer"
39+
40+
# Try fetching the pull request (PR) or issue data
41+
async with self.bot.session.get(
42+
f"https://api.github.com/repos/{repo}/pulls/{num}"
43+
) as pr_response:
44+
pr_data = await pr_response.json()
45+
46+
if "message" not in pr_data:
47+
embed = await self.handle_pr(pr_data, repo)
48+
await msg.channel.send(embed=embed)
49+
return
50+
51+
async with self.bot.session.get(
52+
f"https://api.github.com/repos/{repo}/issues/{num}"
53+
) as issue_response:
54+
issue_data = await issue_response.json()
55+
56+
if "message" not in issue_data:
57+
embed = await self.handle_issue(issue_data, repo)
58+
await msg.channel.send(embed=embed)
59+
60+
async def handle_pr(self, data: dict, repo: str) -> discord.Embed:
61+
# Determine the state of the PR
62+
state = (
63+
"merged"
64+
if data["state"] == "closed" and data.get("merged", False)
65+
else data["state"]
66+
)
67+
embed = self._base(data, repo, is_issue=False)
68+
embed.colour = self.colors["pr"].get(state)
69+
embed.add_field(name="Additions", value=data["additions"], inline=True)
70+
embed.add_field(name="Deletions", value=data["deletions"], inline=True)
71+
embed.add_field(name="Commits", value=data["commits"], inline=True)
72+
embed.set_footer(text=f"Pull Request #{data['number']}")
73+
return embed
74+
75+
async def handle_issue(self, data: dict, repo: str) -> discord.Embed:
76+
embed = self._base(data, repo)
77+
embed.colour = self.colors["issues"].get(data["state"])
78+
embed.set_footer(text=f"Issue #{data['number']}")
79+
return embed
80+
81+
def _base(self, data: dict, repo: str, is_issue: bool = True) -> discord.Embed:
82+
# Truncate the body if it's too long
83+
description = (
84+
f"{data['body'][:2045]}..." if len(data["body"]) > 2048 else data["body"]
85+
)
86+
87+
# Determine the type (Issue or Pull Request)
88+
_type = "Issue" if is_issue else "Pull Request"
89+
title = f"[{repo}] {_type}: #{data['number']} {data['title']}"
90+
title = f"{title[:253]}..." if len(title) > 256 else title
91+
92+
embed = discord.Embed(title=title, url=data["html_url"], description=description)
93+
embed.set_thumbnail(url="https://i.imgur.com/J2uqqol.gif")
94+
embed.set_author(
95+
name=data["user"]["login"],
96+
icon_url=data["user"]["avatar_url"],
97+
url=data["user"]["html_url"],
98+
)
99+
embed.add_field(name="Status", value=data["state"], inline=True)
100+
101+
# Add labels if present
102+
if data.get("labels"):
103+
labels = ", ".join(label["name"] for label in data["labels"])
104+
embed.add_field(name="Labels", value=labels, inline=False)
105+
106+
return embed
107+
108+
109+
async def setup(bot: commands.Bot):
110+
await bot.add_cog(GithubPlugin(bot))

0 commit comments

Comments
 (0)