aboutsummaryrefslogtreecommitdiffstats
path: root/arthur/bot.py
blob: 2220db61fe0614a2f597a871643a5c6e8e6dc890 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
"""Module containing the core bot base for King Arthur."""
from pathlib import Path
from typing import Any, Union

from botcore import BotBase
from botcore.utils import scheduling
from discord import Interaction, Member, User
from discord.ext import commands
from kubernetes_asyncio import config

from arthur import exts, logger
from arthur.config import CONFIG


class KingArthur(BotBase):
    """Base bot class for King Arthur."""

    def __init__(self, *args: list[Any], **kwargs: dict[str, Any]) -> None:
        super().__init__(*args, **kwargs)

        self.add_check(self._is_devops)

    @staticmethod
    def _is_devops(ctx: Union[commands.Context, Interaction]) -> bool:
        """Check all commands are executed by authorised personnel."""
        if isinstance(ctx, Interaction):
            if isinstance(ctx.user, Member):
                return CONFIG.devops_role in [r.id for r in ctx.user.roles]
            else:
                return False

        if ctx.command.name == "ed":
            return True

        if not ctx.guild:
            return False

        return CONFIG.devops_role in [r.id for r in ctx.author.roles]

    async def setup_hook(self) -> None:
        """Async initialisation method for discord.py."""
        await super().setup_hook()

        # Authenticate with Kubernetes
        if (Path.home() / ".kube/config").exists():
            await config.load_kube_config()
        else:
            config.load_incluster_config()
        logger.info(f"Logged in <red>{self.user}</>")

        # This is not awaited to avoid a deadlock with any cogs that have
        # wait_until_guild_available in their cog_load method.
        scheduling.create_task(self.load_extensions(exts))

        logger.info("Loading <red>jishaku</red>")
        await self.load_extension("jishaku")
        logger.info("Loaded <red>jishaku</red>")

    async def is_owner(self, user: Union[User, Member]) -> bool:
        """Check if the invoker is a bot owner."""
        if not user.guild:
            return False

        return CONFIG.devops_role in [r.id for r in user.roles]