This repository has been archived on 2021-03-28. You can view files and clone it, but cannot push or open issues/pull-requests.
frank/frank/frank.py

98 lines
2.5 KiB
Python
Raw Permalink Normal View History

2020-08-25 17:07:27 +02:00
# =====IMPORTS=====
# Future imports
from __future__ import annotations
# Built-in imports
2020-08-08 09:19:09 +02:00
import shlex
2020-08-25 17:07:27 +02:00
# Third-party imports
2020-08-08 09:29:32 +02:00
import yaml
2020-08-25 17:07:27 +02:00
import discord
# Typing imports
from typing import TYPE_CHECKING, List
if TYPE_CHECKING:
# Own imports
from .module import Module
from discord import Message
2020-08-08 09:19:09 +02:00
class Frank(discord.Client):
2020-08-25 17:07:27 +02:00
"""
Main class of the bot; works by adding modules, which all define
their own behavior.
"""
2020-08-25 19:11:45 +02:00
def __init__(self, modules: List[Module], config_file: str = 'frank.yaml',
prefix: str = 'fr'):
2020-08-25 17:07:27 +02:00
"""
Args:
modules: modules to load
config_file: path to yaml config file; ignored if non-existent
2020-08-25 19:11:45 +02:00
prefix: prefix to activate Frank in the Discord server
2020-08-25 17:07:27 +02:00
"""
2020-08-08 09:19:09 +02:00
super().__init__()
self._modules = modules
self._loaded_modules = []
2020-08-25 19:11:45 +02:00
self.PREFIX = prefix
2020-08-08 09:29:32 +02:00
try:
2020-08-25 17:07:27 +02:00
with open(config_file, 'r') as f:
2020-08-08 13:12:09 +02:00
self._config = yaml.load(f, Loader=yaml.FullLoader)
2020-08-08 09:29:32 +02:00
except FileNotFoundError:
2020-08-08 13:12:09 +02:00
self._config = None
2020-08-08 09:29:32 +02:00
2020-08-08 09:19:09 +02:00
async def on_ready(self):
2020-08-26 14:54:55 +02:00
"""
Runs when the bot has succesfully connected to Discord
"""
2020-08-25 17:07:27 +02:00
print('Connected')
2020-08-08 09:19:09 +02:00
# Startup all modules
for module in self._modules:
2020-08-08 13:12:09 +02:00
if self._config and module.NAME in self._config:
loaded = module(self, config=self._config[module.NAME])
2020-08-08 09:29:32 +02:00
else:
loaded = module(self)
2020-08-25 17:07:27 +02:00
await loaded._start()
2020-08-08 09:19:09 +02:00
self._loaded_modules.append(loaded)
2020-08-25 17:07:27 +02:00
print('All modules loaded')
async def stop(self):
2020-08-26 14:54:55 +02:00
"""
Stop all module daemons and exit.
"""
2020-08-25 17:07:27 +02:00
for module in self._loaded_modules:
await module.stop()
2020-08-08 09:19:09 +02:00
2020-08-25 17:07:27 +02:00
async def on_message(self, message: Message):
"""
Runs when a new message is sent in the Discord channel.
Args:
message: object representing the received message; see
https://discordpy.readthedocs.io/en/latest/api.html#message
"""
try:
cmd = shlex.split(message.content.strip())
2020-08-08 09:19:09 +02:00
2020-08-25 17:07:27 +02:00
except ValueError:
return
2020-08-12 18:42:43 +02:00
2020-08-25 17:07:27 +02:00
if cmd and cmd[0] == self.PREFIX:
module = next((mod for mod in self._loaded_modules
if mod.match(cmd[1])), None)
2020-08-08 09:19:09 +02:00
if module:
2020-08-25 17:07:27 +02:00
await module(cmd=cmd[2:], author=message.author,
channel=message.channel, mid=message.id)