Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Event manager #12

Open
wants to merge 7 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ python-dotenv = "*"

[dev-packages]
black = "*"
jishaku = "*"

[requires]
python_version = "3.11"
122 changes: 110 additions & 12 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 23 additions & 4 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
import asyncio
import discord

from src.utils.small_utility import get_env_token, setup_bot
from src.globals.client_instance import DiscordClient

# Initialise singleton with bot instance
intents = discord.Intents.default()
intents.message_content = True
DiscordClient(command_prefix="!", intents=intents, help_command=None)


async def main():
client = await setup_bot()
# Imported after to ensure DiscordClient() isnt called before initial initialization.
from src.utils.small_utility import get_env_token
from src.managers.event_manager import EventManager
from src.managers.cog_system import CogSystem

# Initialise event manager
EventManager()

# Initialise cog system
cog_system = CogSystem(DiscordClient())

# Register all cogs to client
await cog_system.reg_cogs()

# Get token from .env and start up bot accordingly
await client.start(get_env_token("TOKEN"))
await DiscordClient().start(get_env_token("TOKEN"))


if __name__ == '__main__':
if __name__ == "__main__":
asyncio.run(main())
Empty file added src/events/__init__.py
Empty file.
23 changes: 23 additions & 0 deletions src/events/detail/default_events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from src.globals.client_instance import DiscordClient

# List of all available events & the client instance
_discord_client = DiscordClient()


@_discord_client.event
async def on_ready():
from src.managers.event_manager import EventManager

for each in EventManager.on_ready_events:
await each.on_ready()


@_discord_client.event
async def on_message(message):
# Ensures commands work properly, wont process any commands without it.
await _discord_client.process_commands(message)

from src.managers.event_manager import EventManager

for each in EventManager.on_message_events:
await each.on_message(message)
15 changes: 15 additions & 0 deletions src/events/detail/event_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from abc import ABCMeta, abstractmethod


class OnReadyEvent(metaclass=ABCMeta):
@property
@abstractmethod
def on_ready(self):
pass


class OnMessageEvent(metaclass=ABCMeta):
@property
@abstractmethod
def on_message(self, message):
pass
16 changes: 16 additions & 0 deletions src/events/language_filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from src.events.detail.event_base import OnMessageEvent
from src.globals.client_instance import DiscordClient


class LanguageFilter(OnMessageEvent):
# TODO: Ship them in a file, and create the ability to add/remove words runtime.
kBadWordsList = ["kanker", "flikker", "can3cer"]

async def on_message(self, message) -> None:
for bad_word in self.kBadWordsList:
if bad_word in message.content.lower():
await message.delete()
await message.channel.send(
f"Hey {message.author.mention}, keep it civil blud."
)
break
6 changes: 6 additions & 0 deletions src/events/print_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from src.events.detail.event_base import OnMessageEvent


class PrintMessage(OnMessageEvent):
async def on_message(self, message) -> None:
print(f"Message {message.author}: {message.content}")
7 changes: 7 additions & 0 deletions src/events/welcome_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from src.events.detail.event_base import OnReadyEvent
from src.globals.client_instance import DiscordClient


class WelcomeMessage(OnReadyEvent):
async def on_ready(self) -> None:
print(f"Logged on as {DiscordClient().user}!")
Empty file added src/globals/__init__.py
Empty file.
8 changes: 8 additions & 0 deletions src/globals/client_instance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from discord.ext import commands

from src.utils.singleton import Singleton


# NOTE: Skeleton of the client to ensure only one object of commands.bot is created by utilising a singleton
class DiscordClient(commands.Bot, metaclass=Singleton):
pass
16 changes: 0 additions & 16 deletions src/managers/discord_client.py

This file was deleted.

26 changes: 26 additions & 0 deletions src/managers/event_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Initialises all default events
from src.events.detail.default_events import *


# Manages the events
class EventManager:
# Declare static member lists of event objects
on_ready_events = []
on_message_events = []

def __init__(self):
# Create & register events
self.register_events()

def register_events(self):
# Please include the py module that contains your feature and create an instance
# fmt: off
from src.events.welcome_message import WelcomeMessage
self.on_ready_events.append(WelcomeMessage())

from src.events.print_message import PrintMessage
self.on_message_events.append(PrintMessage())

from src.events.language_filter import LanguageFilter
self.on_message_events.append(LanguageFilter())
# fmt: on
7 changes: 7 additions & 0 deletions src/utils/singleton.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Singleton(type):
_instances = {}

def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
27 changes: 0 additions & 27 deletions src/utils/small_utility.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import os
import os.path
import discord

from dotenv import load_dotenv

from src.managers.discord_client import DiscordClient
from src.managers.cog_system import CogSystem


# TODO: Impl proper error handling
def get_env_token(req_token):
Expand All @@ -22,26 +18,3 @@ def get_env_token(req_token):
exit(1)

return token


async def _create_client_instance():
# New python API update requires these
intents = discord.Intents.default()
intents.message_content = True

# Create discord bot instance
return DiscordClient(command_prefix="!", intents=intents, help_command=None)


async def setup_bot():
# Create discord bot instance
client = await _create_client_instance()

# Initialise cog system
cog_system = CogSystem(client)

# Register all cogs to client
await cog_system.reg_cogs()

# Return client so the .start() can be ran
return client