-
Notifications
You must be signed in to change notification settings - Fork 1
/
app.py
120 lines (99 loc) · 3.17 KB
/
app.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
from anathema import datetime_curse # isort: skip
import asyncio
import datetime
import logging
import pathlib
import signal
import traceback
import zoneinfo
from logging.handlers import TimedRotatingFileHandler
import asyncpg
import discord
import jishaku
from discord.ext import commands
import core
discord.VoiceClient.warn_nacl = False
jishaku.Flags.NO_UNDERSCORE = True
jishaku.Flags.NO_DM_TRACEBACK = True
#jishaku.Flags.HIDE = True
ROOT = logging.getLogger()
ROOT.setLevel(logging.INFO)
pathlib.Path("bot_log").mkdir(exist_ok=True)
filer = TimedRotatingFileHandler(
filename="bot_log/nanika_bot.log",
encoding="utf-8",
#maxBytes=32 * 1024 * 1024,
backupCount=7 * 8, # 8 weeks worth
atTime=datetime.time(hour=0, minute=0, tzinfo=zoneinfo.ZoneInfo("Australia/Melbourne"))
)
filer.setFormatter(
logging.Formatter(
"[{asctime}] [{levelname:<8}] {name}: {message}",
style="{",
datefmt="%Y-%m-%d %H:%M:%S"
)
)
ROOT.addHandler(filer)
class PastelColourFormatter(logging.Formatter):
COLOURS = {
logging.DEBUG: "85",
logging.INFO: "225",
logging.WARNING: "209",
logging.ERROR: "140",
logging.CRITICAL: "1",
}
def __init__(self):
super().__init__(
"[{asctime}] [{levelname:<8}] {name}: {message}",
style="{",
datefmt="%Y-%m-%d %H:%M:%S"
)
def format(self, record):
# logging caches the formatted trace
original = record.exc_text
record.exc_text = None
fmt = super().format(record)
record.exc_text = original
code = self.COLOURS[record.levelno]
return "\n".join([
f"\x1b[38;5;{code}m{line}\x1b[0m"
for line in fmt.splitlines()
])
def formatException(self, exc_info):
fmt = traceback.format_exception(*exc_info)
colour = self.COLOURS[logging.ERROR]
return "\n".join([
f"\x1b[38;5;{colour}m{line}\x1b[0m"
for each_line in fmt
# some lines contain internal newlines
for line in each_line.splitlines()
])
writer = logging.StreamHandler()
writer.setFormatter(PastelColourFormatter())
ROOT.addHandler(writer)
class KeyboardInterruptHandler:
def __init__(self):
self.bot = None
self._pending = False
def __call__(self, code, frame):
if self._pending or not self.bot:
raise KeyboardInterrupt
self.bot.loop.call_soon_threadsafe(
self.bot.loop.create_task,
self.bot.close()
)
self.bot.loop.call_soon_threadsafe(lambda: None) # no-op to wake up loop (important!)
self._pending = True
def bind_bot(self, bot: commands.Bot):
self.bot = bot
on_sigint = KeyboardInterruptHandler()
signal.signal(signal.SIGINT, on_sigint)
#signal.siginterrupt(signal.SIGINT, False)
async def main():
async with asyncpg.create_pool(core.configs["postgresql"]["uri"]) as pool:
async with core.nanika_bot(asyncpg_pool=pool) as n:
on_sigint.bind_bot(n)
await n.start(core.configs["discord"]["token"])
ROOT.info("no more asyncio")
asyncio.run(main())
ROOT.info("there is nothing else")