-
Notifications
You must be signed in to change notification settings - Fork 0
/
bot.py
95 lines (76 loc) · 3.32 KB
/
bot.py
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
from __future__ import annotations
import os
import dotenv
import asyncio
import aiohttp
import discord
import asyncpg
import traceback
from datetime import time, datetime, timezone
from logging import getLogger
from typing import TYPE_CHECKING
from discord.ext import commands, tasks
if TYPE_CHECKING:
from cogs.aoc import AOC
log = getLogger('bot')
INITIAL_EXTENSIONS = ['cogs.errorhandler', 'jishaku'] + (['cogs.aoc'] if datetime.now().month == 12 else [])
def get(k: str) -> str:
v = os.getenv(k)
if not v:
raise RuntimeError("'%s' not set in the .env file!" % k)
return v
class AOCBot(commands.Bot):
"""The Advent Of Code Bot for the Duck Hideout guild"""
def __init__(self, pool: asyncpg.Pool, session: aiohttp.ClientSession) -> None:
status = discord.Status.online if datetime.now().month == 12 else discord.Status.offline
super().__init__(
intents=discord.Intents(guilds=True, members=True, messages=True),
command_prefix=commands.when_mentioned,
status=status,
help_command=None,
activity=discord.Activity(type=discord.ActivityType.listening, name='/link'),
)
self.pool: asyncpg.Pool[asyncpg.Record] = pool
self.session: aiohttp.ClientSession = session
async def setup_hook(self) -> None:
"""|coro| A coroutine called by the library between .login() and .connect()"""
for extension in INITIAL_EXTENSIONS:
try:
await self.load_extension(extension)
log.info('Loaded extension %s', extension)
except:
log.error("Failed to load %s:\n%s", extension, traceback.format_exc())
@tasks.loop(time=time(hour=0, tzinfo=timezone.utc))
async def check_for_times(self):
if datetime.now().month == 12:
if 'cogs.aoc' not in self.extensions.keys():
await self.load_extension('cogs.aoc')
await self.tree.sync()
if self.status == discord.Status.offline:
self.status = discord.Status.offline
await self.change_presence(status=discord.Status.online)
else:
if 'cogs.aoc' in self.extensions.keys():
cog: AOC = self.get_cog('AOC') # type: ignore
if cog:
await cog.clear_names()
await self.unload_extension('cogs.aoc')
await self.tree.sync()
if self.status == discord.Status.online:
self.status = discord.Status.offline
await self.change_presence(status=discord.Status.offline)
@check_for_times.before_loop
async def ctf_before(self):
await self.wait_until_ready()
async def on_ready(self) -> None:
"""|coro| Called when the bot's internal cache is ready."""
log.info("Logged in as %s", str(self.user))
async def on_error(self, event_method: str, /, *args, **kwargs) -> None:
log.error("Error in event '%s'\n%s", event_method, traceback.format_exc())
if __name__ == "__main__":
dotenv.load_dotenv()
async def startup():
async with asyncpg.create_pool(get("DSN")) as pool, aiohttp.ClientSession() as session, AOCBot(pool, session) as bot:
discord.utils.setup_logging()
await bot.start(token=get("TOKEN"))
asyncio.run(startup())