aboutsummaryrefslogtreecommitdiffstats
path: root/arthur/exts/fun/devops_rules.py
diff options
context:
space:
mode:
authorGravatar Chris Lovering <[email protected]>2022-10-07 13:54:54 +0100
committerGravatar Chris Lovering <[email protected]>2022-10-07 21:00:45 +0100
commit4716123f6bfd2af7ade27115e906c26cf6ce5208 (patch)
treefb84f7f51dbba2821361a1df5295621633116706 /arthur/exts/fun/devops_rules.py
parentMerge pull request #25 from python-discord/poetry-1.2 (diff)
Add devops rules command
Diffstat (limited to 'arthur/exts/fun/devops_rules.py')
-rw-r--r--arthur/exts/fun/devops_rules.py94
1 files changed, 94 insertions, 0 deletions
diff --git a/arthur/exts/fun/devops_rules.py b/arthur/exts/fun/devops_rules.py
new file mode 100644
index 0000000..47d1720
--- /dev/null
+++ b/arthur/exts/fun/devops_rules.py
@@ -0,0 +1,94 @@
+"""The rules all devops members must follow."""
+
+from typing import TypedDict
+
+import discord
+from discord.ext.commands import Cog, Context, Greedy, command
+
+from arthur.bot import KingArthur
+from arthur.config import CONFIG
+
+NOTION_API_BASE_URL = "https://api.notion.com/v1"
+DEVOPS_RULES_PAGE_CONTENT = (
+ f"{NOTION_API_BASE_URL}/blocks/149bc48f-6f79-47af-add8-036f11d4e9a7/children"
+)
+DISCORD_MARKDOWN_LOOKUP = {
+ "bold": "**{}**",
+ "italic": "_{}_",
+ "strikethrough": "~~{}~~",
+ "underline": "__{}__",
+}
+
+
+class NotionAnnotations(TypedDict):
+ """The markdown annotations attached to a block of text in Notion."""
+
+ bold: bool
+ italic: bool
+ strikethrough: bool
+ underline: bool
+
+
+class NotionRichText(TypedDict):
+ """A block of text with markdown annotations attached."""
+
+ plain_text: str
+ annotations: NotionAnnotations
+
+
+def notion_block_to_discord_markdown(block: list[NotionRichText]) -> str:
+ """Convert the given notion API "block" into Discord markdown text."""
+ block_string_parts = []
+ for rich_text_part in block:
+ block_string_part = rich_text_part["plain_text"]
+ for annotation, enabled in rich_text_part["annotations"].items():
+ if enabled and annotation in DISCORD_MARKDOWN_LOOKUP:
+ block_string_part = DISCORD_MARKDOWN_LOOKUP[annotation].format(block_string_part)
+ block_string_parts.append(block_string_part)
+ return "".join(block_string_parts)
+
+
+class Rules(Cog):
+ """The rules all devops members must follow."""
+
+ def __init__(self, bot: KingArthur) -> None:
+ self.bot = bot
+ self.rules: dict
+
+ async def cog_load(self) -> None:
+ """Fetch Devops rules from notion of cog load."""
+ headers = {
+ "Authorization": f"Bearer {CONFIG.notion_api_token}",
+ "accept": "application/json",
+ "Notion-Version": "2022-06-28",
+ }
+ async with self.bot.http_session.get(DEVOPS_RULES_PAGE_CONTENT, headers=headers) as resp:
+ resp.raise_for_status()
+ page_content = await resp.json()
+
+ self.rules = {
+ i: notion_block_to_discord_markdown(block["numbered_list_item"]["rich_text"])
+ for i, block in enumerate(page_content["results"], 1)
+ if block.get("type") == "numbered_list_item"
+ }
+
+ @command(name="rules", aliases=("rule",))
+ async def get_rules(self, ctx: Context, rules: Greedy[int]) -> None:
+ """List the requested rule(s), or all of them if not defined."""
+ output_rules = set(rules) or self.rules.keys()
+ output = "\n".join(
+ f"{key}: {value}"
+ for key, value in self.rules.items()
+ if key in output_rules
+ )
+ await ctx.send(embed=discord.Embed(
+ title=f"Rule{'s'[:len(output_rules)^1]}",
+ description=output,
+ colour=discord.Colour.og_blurple(),
+ url="https://www.notion.so/pythondiscord/Rules-149bc48f6f7947afadd8036f11d4e9a7",
+ ))
+
+
+async def setup(bot: KingArthur) -> None:
+ """Add cog to bot."""
+ await bot.add_cog(Rules(bot))