From dae062257a56ccc675cb04e4dd0ce5ed5de133d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?JelNiS=C5=82aw?= Date: Wed, 30 Mar 2022 20:36:48 +0200 Subject: [PATCH] Add auto GitHub repo embedding --- wulkabot/bot.py | 2 +- wulkabot/cogs/github.py | 60 +++++++++++++++++++++++++++ wulkabot/{cogs => }/utils/__init__.py | 0 wulkabot/utils/github.py | 21 ++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 wulkabot/cogs/github.py rename wulkabot/{cogs => }/utils/__init__.py (100%) create mode 100644 wulkabot/utils/github.py diff --git a/wulkabot/bot.py b/wulkabot/bot.py index c749265..842a6e7 100644 --- a/wulkabot/bot.py +++ b/wulkabot/bot.py @@ -23,8 +23,8 @@ class Wulkabot(commands.Bot): ) async def setup_hook(self) -> None: - await self.load_extensions(cogs) self.http_client = aiohttp.ClientSession() + await self.load_extensions(cogs) async def on_connect(self) -> None: print(f"Connected as {self.user}") diff --git a/wulkabot/cogs/github.py b/wulkabot/cogs/github.py new file mode 100644 index 0000000..2ac89b6 --- /dev/null +++ b/wulkabot/cogs/github.py @@ -0,0 +1,60 @@ +""" +Wulkabot +Copyright (C) 2022-present Stanisław Jelnicki +""" + +import re +from typing import Any + +import aiohttp + +# from discord import app_commands +import discord +from discord.ext import commands + +from ..utils import github + +GITHUB_REPO = re.compile(r"(?:\s|^)(?P[\w-]+)/(?P[\w-]+)(?:\s|$)", re.ASCII) + + +def match_repo(text: str) -> tuple[str, str] | None: + if match := GITHUB_REPO.search(text): + return (match["owner"], match["repo"]) + + +def github_repo_embed(repo: dict[str, Any]) -> discord.Embed: + description = repo["description"] + if homepage := repo["homepage"]: + description += f"\n\n{homepage}" + stargazers_count = repo["stargazers_count"] + forks_count = repo["forks_count"] + watchers = repo["watchers"] + footer = f"⭐ {stargazers_count} 🍴 {forks_count} 👀 {watchers}" + + return ( + discord.Embed(title=repo["full_name"], url=repo["html_url"], description=description) + .set_thumbnail(url=repo["owner"]["avatar_url"]) + .set_footer(text=footer) + ) + + +class GitHub(commands.Cog): + def __init__(self) -> None: + super().__init__() + self.github = github.GitHub(aiohttp.ClientSession(base_url="https://api.github.com")) + + async def cog_unload(self) -> None: + await self.github.close() + + @commands.Cog.listener() + async def on_message(self, message: discord.Message) -> None: + if message.author.bot: + return + + if match := match_repo(message.content): + if repo := await self.github.fetch_repo(*match): + await message.reply(embed=github_repo_embed(repo)) + + +async def setup(bot: commands.Bot): + await bot.add_cog(GitHub()) diff --git a/wulkabot/cogs/utils/__init__.py b/wulkabot/utils/__init__.py similarity index 100% rename from wulkabot/cogs/utils/__init__.py rename to wulkabot/utils/__init__.py diff --git a/wulkabot/utils/github.py b/wulkabot/utils/github.py new file mode 100644 index 0000000..536e40c --- /dev/null +++ b/wulkabot/utils/github.py @@ -0,0 +1,21 @@ +""" +Wulkabot +Copyright (C) 2022-present Stanisław Jelnicki +""" + +from typing import Any + +import aiohttp + + +class GitHub: + def __init__(self, http_client: aiohttp.ClientSession) -> None: + self._http = http_client + + async def fetch_repo(self, owner: str, repo: str) -> dict[str, Any] | None: + response = await self._http.get(f"/repos/{owner}/{repo}") + if response.ok: + return await response.json() + + async def close(self): + await self.close()