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

111 lines
2.6 KiB
Python
Raw 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
2020-08-25 17:07:27 +02:00
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.
"""
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:
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)
print("All modules loaded")
2020-08-25 17:07:27 +02:00
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-27 17:23:38 +02:00
# Exit if no commands are given or prefix is wrong
if not (cmd and cmd[0] == self.PREFIX):
return
module = next(
(mod for mod in self._loaded_modules if mod.match(cmd[1])), None
)
2020-08-08 09:19:09 +02:00
2020-08-27 17:23:38 +02:00
if module:
await module(
cmd=cmd[2:],
author=message.author,
channel=message.channel,
mid=message.id,
)