Core bot framework

This commit is contained in:
2021-08-25 22:56:45 +03:00
parent 87f16b6a37
commit 05cb9650ee
17 changed files with 1233 additions and 0 deletions

3
bot/meta/__init__.py Normal file
View File

@@ -0,0 +1,3 @@
from .client import client
from .config import conf
from .logger import log, logger

13
bot/meta/client.py Normal file
View File

@@ -0,0 +1,13 @@
from cmdClient.cmdClient import cmdClient
from .config import Conf
from constants import CONFIG_FILE
# Initialise config
conf = Conf(CONFIG_FILE)
# Initialise client
owners = [int(owner) for owner in conf.bot.getlist('owners')]
client = cmdClient(prefix=conf.bot['prefix'], owners=owners)
client.conf = conf

59
bot/meta/config.py Normal file
View File

@@ -0,0 +1,59 @@
import configparser as cfgp
conf = None # type: Conf
CONF_FILE = "bot/bot.conf"
class Conf:
def __init__(self, configfile, section_name="DEFAULT"):
self.configfile = configfile
self.config = cfgp.ConfigParser(
converters={
"intlist": self._getintlist,
"list": self._getlist,
}
)
self.config.read(configfile)
self.section_name = section_name if section_name in self.config else 'DEFAULT'
self.default = self.config["DEFAULT"]
self.section = self.config[self.section_name]
self.bot = self.section
# Config file recursion, read in configuration files specified in every "ALSO_READ" key.
more_to_read = self.section.getlist("ALSO_READ", [])
read = set()
while more_to_read:
to_read = more_to_read.pop(0)
read.add(to_read)
self.config.read(to_read)
new_paths = [path for path in self.section.getlist("ALSO_READ", [])
if path not in read and path not in more_to_read]
more_to_read.extend(new_paths)
global conf
conf = self
def __getitem__(self, key):
return self.section[key].strip()
def __getattr__(self, section):
return self.config[section]
def get(self, name, fallback=None):
result = self.section.get(name, fallback)
return result.strip() if result else result
def _getintlist(self, value):
return [int(item.strip()) for item in value.split(',')]
def _getlist(self, value):
return [item.strip() for item in value.split(',')]
def write(self):
with open(self.configfile, 'w') as conffile:
self.config.write(conffile)

72
bot/meta/logger.py Normal file
View File

@@ -0,0 +1,72 @@
import sys
import logging
import asyncio
from discord import AllowedMentions
from cmdClient.logger import cmd_log_handler
from utils.lib import mail, split_text
from .client import client
from .config import conf
# Setup the logger
logger = logging.getLogger()
log_fmt = logging.Formatter(fmt='[{asctime}][{levelname:^8}] {message}', datefmt='%d/%m | %H:%M:%S', style='{')
term_handler = logging.StreamHandler(sys.stdout)
term_handler.setFormatter(log_fmt)
logger.addHandler(term_handler)
logger.setLevel(logging.INFO)
# Define the context log format and attach it to the command logger as well
@cmd_log_handler
def log(message, context="GLOBAL", level=logging.INFO, post=True):
# Add prefixes to lines for better parsing capability
lines = message.splitlines()
if len(lines) > 1:
lines = [
'' * (i == 0) + '' * (0 < i < len(lines) - 1) + '' * (i == len(lines) - 1) + line
for i, line in enumerate(lines)
]
else:
lines = ['' + message]
for line in lines:
logger.log(level, '\b[{}] {}'.format(
str(context).center(22, '='),
line
))
# Fire and forget to the channel logger, if it is set up
if post and client.is_ready():
asyncio.ensure_future(live_log(message, context, level))
# Live logger that posts to the logging channels
async def live_log(message, context, level):
if level >= logging.INFO:
log_chid = conf.bot.getint('log_channel')
# Generate the log messages
header = "[{}][{}]".format(logging.getLevelName(level), str(context))
if len(message) > 1900:
blocks = split_text(message, blocksize=1900, code=False)
else:
blocks = [message]
if len(blocks) > 1:
blocks = [
"```md\n{}[{}/{}]\n{}\n```".format(header, i+1, len(blocks), block) for i, block in enumerate(blocks)
]
else:
blocks = ["```md\n{}\n{}\n```".format(header, blocks[0])]
# Post the log messages
if log_chid:
[await mail(client, log_chid, content=block, allowed_mentions=AllowedMentions.none()) for block in blocks]
# Attach logger to client, for convenience
client.log = log