Skip to content

Commit 19a9cf7

Browse files
committed
Add Support for aliases repositories & default org in .gh repo command
1 parent cb14fcf commit 19a9cf7

File tree

2 files changed

+138
-55
lines changed

2 files changed

+138
-55
lines changed

bot/exts/utilities/githubinfo.py

Lines changed: 134 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
from dataclasses import dataclass
44
from datetime import UTC, datetime
55
from urllib.parse import quote
6+
from pathlib import Path
7+
import json
68

79
import discord
810
from aiohttp import ClientResponse
9-
from discord.ext import commands
11+
from discord.ext import commands, tasks
1012
from pydis_core.utils.logging import get_logger
1113

1214
from bot.bot import Bot
@@ -21,6 +23,7 @@
2123
}
2224

2325
REPOSITORY_ENDPOINT = "https://api.github.com/orgs/{org}/repos?per_page=100&type=public"
26+
FETCH_MOST_STARRED_ENDPOINT = "https://api.github.com/search/repositories?q={name}&sort=stars&order=desc&per_page=1"
2427
ISSUE_ENDPOINT = "https://api.github.com/repos/{user}/{repository}/issues/{number}"
2528
PR_ENDPOINT = "https://api.github.com/repos/{user}/{repository}/pulls/{number}"
2629

@@ -78,6 +81,16 @@ def __init__(self, bot: Bot):
7881
self.bot = bot
7982
self.repos = []
8083

84+
async def cog_load(self):
85+
self.refresh_repos.start()
86+
87+
self.stored_repos_json = Path(__file__).parent.parent.parent / "resources" / "utilities" / "stored_repos.json"
88+
89+
with open(self.stored_repos_json, "r") as f:
90+
self.stored_repos = json.load(f)
91+
log.info("Loaded stored repos in memory.")
92+
93+
8194
@staticmethod
8295
def remove_codeblocks(message: str) -> str:
8396
"""Remove any codeblock in a message."""
@@ -293,78 +306,144 @@ async def github_user_info(self, ctx: commands.Context, username: str) -> None:
293306

294307
await ctx.send(embed=embed)
295308

309+
@tasks.loop(hours=24)
310+
async def refresh_repos(self):
311+
self.repos, _ = await self.fetch_data(REPOSITORY_ENDPOINT.format(org="python-discord"))
312+
log.info(f"Loaded {len(self.repos)} repos from Python Discord org into memory.")
313+
296314
@github_group.command(name="repository", aliases=("repo",))
297315
async def github_repo_info(self, ctx: commands.Context, *repo: str) -> None:
298316
"""
299-
Fetches a repositories' GitHub information.
317+
Fetches a repository's GitHub information.
300318
301319
The repository should look like `user/reponame` or `user reponame`.
320+
If it's not a stored repo or PyDis repo, it will fetch the most-starred repo
321+
matching the search query from GitHub.
302322
"""
303-
repo = "/".join(repo)
304-
if repo.count("/") != 1:
305-
embed = discord.Embed(
306-
title=random.choice(NEGATIVE_REPLIES),
307-
description="The repository should look like `user/reponame` or `user reponame`.",
308-
colour=Colours.soft_red
309-
)
310-
311-
await ctx.send(embed=embed)
312-
return
323+
is_pydis = False
324+
fetch_most_starred = False
325+
repo_query = "/".join(repo)
326+
327+
# Determine type of repo
328+
if repo_query.count("/") != 1:
329+
if repo_query in self.stored_repos:
330+
repo_query = self.stored_repos[repo_query]
331+
else:
332+
for each in self.repos:
333+
if repo_query == each['name']:
334+
repo_query = each['full_name']
335+
is_pydis = True
336+
break
337+
else:
338+
fetch_most_starred = True
313339

314340
async with ctx.typing():
315-
repo_data, _ = await self.fetch_data(f"{GITHUB_API_URL}/repos/{quote(repo)}")
316-
317-
# There won't be a message key if this repo exists
318-
if "message" in repo_data:
341+
# Case 1: PyDis repo
342+
if is_pydis:
343+
for each in self.repos:
344+
if repo_query == each['full_name']:
345+
repo_data = each
346+
break
347+
348+
# Case 2: Not stored or PyDis, fetch most-starred matching repo
349+
elif fetch_most_starred:
350+
repo_data, _ = await self.fetch_data(FETCH_MOST_STARRED_ENDPOINT.format(name=quote(repo_query)))
351+
352+
if not repo_data['items']:
353+
embed = discord.Embed(
354+
title=random.choice(NEGATIVE_REPLIES),
355+
description=f"No repositories found matching `{repo_query}`.",
356+
colour=Colours.soft_red
357+
)
358+
await ctx.send(embed=embed)
359+
return
360+
361+
repo_item = repo_data['items'][0] # Top result
319362
embed = discord.Embed(
320-
title=random.choice(NEGATIVE_REPLIES),
321-
description="The requested repository was not found.",
322-
colour=Colours.soft_red
363+
title=repo_item["name"],
364+
description=repo_item["description"] or "No description provided.",
365+
colour=discord.Colour.og_blurple(),
366+
url=repo_item["html_url"]
323367
)
324368

325-
await ctx.send(embed=embed)
326-
return
327-
328-
embed = discord.Embed(
329-
title=repo_data["name"],
330-
description=repo_data["description"],
331-
colour=discord.Colour.og_blurple(),
332-
url=repo_data["html_url"]
333-
)
369+
repo_owner = repo_item["owner"]
370+
embed.set_author(
371+
name=repo_owner["login"],
372+
url=repo_owner["html_url"],
373+
icon_url=repo_owner["avatar_url"]
374+
)
334375

335-
# If it's a fork, then it will have a parent key
336-
try:
337-
parent = repo_data["parent"]
338-
embed.description += f"\n\nForked from [{parent['full_name']}]({parent['html_url']})"
339-
except KeyError:
340-
log.debug("Repository is not a fork.")
376+
repo_created_at = datetime.strptime(
377+
repo_item["created_at"], "%Y-%m-%dT%H:%M:%SZ"
378+
).replace(tzinfo=UTC).strftime("%d/%m/%Y")
379+
last_pushed = datetime.strptime(
380+
repo_item["pushed_at"], "%Y-%m-%dT%H:%M:%SZ"
381+
).replace(tzinfo=UTC).strftime("%d/%m/%Y at %H:%M")
382+
383+
embed.set_footer(
384+
text=(
385+
f"{repo_item['forks_count']} ⑂ "
386+
f"• {repo_item['stargazers_count']} ⭐ "
387+
f"• Created At {repo_created_at} "
388+
f"• Last Commit {last_pushed}"
389+
)
390+
)
341391

342-
repo_owner = repo_data["owner"]
392+
await ctx.send(embed=embed)
393+
return
343394

344-
embed.set_author(
345-
name=repo_owner["login"],
346-
url=repo_owner["html_url"],
347-
icon_url=repo_owner["avatar_url"]
348-
)
395+
# Case 3: Regular GitHub repo
396+
else:
397+
repo_data, _ = await self.fetch_data(f"{GITHUB_API_URL}/repos/{quote(repo_query)}")
398+
399+
if "message" in repo_data:
400+
embed = discord.Embed(
401+
title=random.choice(NEGATIVE_REPLIES),
402+
description="The requested repository was not found.",
403+
colour=Colours.soft_red
404+
)
405+
await ctx.send(embed=embed)
406+
return
407+
408+
# Embed creation for PyDis or regular GitHub repo
409+
embed = discord.Embed(
410+
title=repo_data["name"],
411+
description=repo_data["description"] or "No description provided.",
412+
colour=discord.Colour.og_blurple(),
413+
url=repo_data["html_url"]
414+
)
349415

350-
repo_created_at = datetime.strptime(
351-
repo_data["created_at"], "%Y-%m-%dT%H:%M:%SZ"
352-
).replace(tzinfo=UTC).strftime("%d/%m/%Y")
353-
last_pushed = datetime.strptime(
354-
repo_data["pushed_at"], "%Y-%m-%dT%H:%M:%SZ"
355-
).replace(tzinfo=UTC).strftime("%d/%m/%Y at %H:%M")
356-
357-
embed.set_footer(
358-
text=(
359-
f"{repo_data['forks_count']} ⑂ "
360-
f"• {repo_data['stargazers_count']} ⭐ "
361-
f"• Created At {repo_created_at} "
362-
f"• Last Commit {last_pushed}"
416+
# Fork info
417+
try:
418+
parent = repo_data["parent"]
419+
embed.description += f"\n\nForked from [{parent['full_name']}]({parent['html_url']})"
420+
except KeyError:
421+
log.debug("Repository is not a fork.")
422+
423+
repo_owner = repo_data["owner"]
424+
embed.set_author(
425+
name=repo_owner["login"],
426+
url=repo_owner["html_url"],
427+
icon_url=repo_owner["avatar_url"]
363428
)
364-
)
365429

366-
await ctx.send(embed=embed)
430+
repo_created_at = datetime.strptime(
431+
repo_data["created_at"], "%Y-%m-%dT%H:%M:%SZ"
432+
).replace(tzinfo=UTC).strftime("%d/%m/%Y")
433+
last_pushed = datetime.strptime(
434+
repo_data["pushed_at"], "%Y-%m-%dT%H:%M:%SZ"
435+
).replace(tzinfo=UTC).strftime("%d/%m/%Y at %H:%M")
436+
437+
embed.set_footer(
438+
text=(
439+
f"{repo_data['forks_count']} ⑂ "
440+
f"• {repo_data['stargazers_count']} ⭐ "
441+
f"• Created At {repo_created_at} "
442+
f"• Last Commit {last_pushed}"
443+
)
444+
)
367445

446+
await ctx.send(embed=embed)
368447

369448
async def setup(bot: Bot) -> None:
370449
"""Load the GithubInfo cog."""
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"kubernetes": "kubernetes/kubernetes",
3+
"discord.py": "Rapptz/discord.py"
4+
}

0 commit comments

Comments
 (0)