-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
137 lines (112 loc) · 3.75 KB
/
main.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import asyncio
import logging
import os
from typing import Any, Type
from aiohttp import ClientSession
import asyncpg
import discord
from discord.ext import commands
from dotenv import load_dotenv
load_dotenv()
import cogs
from base.context import CustomContext
from utils.logger import ErrorHandler, InfoHandler
class AdvancedBot(commands.Bot):
"""A single-line docstring giving a brief description of the bot"""
def __init__(
self,
*args,
db_pool: asyncpg.Pool,
logger: logging.Logger,
session: ClientSession,
**kwargs,
):
# It is good practice to manually specify every intent that you will use
# instead of using discord.Intents.all()
intents = discord.Intents(
guilds=True,
messages=True,
message_content=True,
# TODO: Add specific intents as you like
# Ref: https://discordpy.readthedocs.io/en/stable/api.html#discord.Intents
)
super().__init__(
*args,
**kwargs,
command_prefix=self._prefix_callable,
intents=intents,
)
self.pool = db_pool
self.launch_time = discord.utils.utcnow()
self.logger = logger
self.session = session
@staticmethod
async def _prefix_callable(bot, message: discord.Message) -> list:
"""Return the bot's prefix for a guild or a DM"""
await bot.wait_until_ready()
if os.getenv("DEV") == "1":
DEFAULT_PREFIX = "!"
else:
DEFAULT_PREFIX = "%"
prefixes = [DEFAULT_PREFIX]
if message.guild is None:
return prefixes
# TODO: Use this if you want saved prefixes
# saved_prefixes = await bot.pool.fetch(
# "SELECT prefix FROM guild_prefix WHERE guild_id = $1",
# message.guild.id,
# )
# if saved_prefixes:
# prefixes = [prefix["prefix"] for prefix in saved_prefixes]
return prefixes
async def get_context(
self,
origin: discord.Message | discord.Interaction,
/,
*,
cls: Type = None,
) -> Any:
return await super().get_context(origin, cls=cls or CustomContext)
async def on_ready(self):
assert self.user is not None
self.logger.info(f"Logged in as {self.user} (ID: {self.user.id})")
async def setup_hook(self) -> None:
if os.getenv("DEV") == 1:
self.logger.addHandler(ErrorHandler(self.loop, self.session))
results = await asyncio.gather(
*(self.load_extension(ext) for ext in cogs.INITIAL_EXTENSIONS),
return_exceptions=True,
)
for ext, result in zip(cogs.INITIAL_EXTENSIONS, results):
if isinstance(result, Exception):
self.logger.error(f"Failed to load extension `{ext}`: {result}")
async def main():
dev_bot_token = os.getenv("DEV_BOT_TOKEN")
bot_token = os.getenv("BOT_TOKEN")
assert bot_token is not None
logger = logging.getLogger("AdvancedBot")
logger.setLevel(logging.DEBUG)
logger.addHandler(InfoHandler())
discord.utils.setup_logging(level=logging.INFO, root=False)
pool = asyncpg.create_pool(
dsn=os.getenv("DATABASE_URL"),
command_timeout=60,
max_inactive_connection_lifetime=0,
)
session = ClientSession()
bot = AdvancedBot(
db_pool=pool,
logger=logger,
session=session,
)
async with session, pool, bot:
if os.getenv("DEV") == "1":
assert dev_bot_token is not None
await bot.start(dev_bot_token)
else:
await bot.start(bot_token)
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
pass