Skip to content

Commit

Permalink
WIP: service injector
Browse files Browse the repository at this point in the history
  • Loading branch information
tristiisch committed Sep 9, 2024
1 parent a767a4b commit 6536bdb
Show file tree
Hide file tree
Showing 13 changed files with 169 additions and 24 deletions.
4 changes: 1 addition & 3 deletions src/pyramid/connector/discord/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ def __init__(self, logger: logging.Logger, information: ApplicationInfo, config:
self.__ffmpeg = config.discord__ffmpeg
self.__environment: Environment = config.mode
self.__engine_source = EngineSource(config)
self.__started = time.time()

intents = discord.Intents.default()
# intents.members = True
Expand All @@ -68,8 +67,7 @@ def create(self, health: HealthModules):
self.__get_guild_cmd,
self.__logger,
self.__information,
self.__environment,
self.__started,
self.__environment
)
self._health = health

Expand Down
16 changes: 12 additions & 4 deletions src/pyramid/connector/discord/bot_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,28 @@ def __init__(
get_guild_cmd: Callable[[Guild], GuildCmd],
logger: Logger,
info: ApplicationInfo,
environment: Environment,
started: float,
environment: Environment
):
self.__bot = bot
self.__get_guild_cmd = get_guild_cmd
self.__logger = logger
self.__info = info
self.__environment = environment
self.__started = started

def register(self):
bot = self.__bot

register_commands(self.__bot, self.__logger, self.__environment.name.lower())
services: dict[str, object] = dict()

service = self.__environment
service_name = service.__class__.__name__
services[service_name] = service

service = self.__info
service_name = service.__class__.__name__
services[service_name] = service

register_commands(services, self.__bot, self.__logger, self.__environment.name.lower())

# ping = PingCommand(ParametersCommand("ping"), self.__bot, self.__logger)
# ping.register(self.__environment.name.lower())
Expand Down
10 changes: 9 additions & 1 deletion src/pyramid/connector/discord/commands/about_command.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@

import time
from discord import AppInfo, ClientUser, Color, Embed, Interaction
from discord.user import BaseUser
from pyramid.connector.discord.commands.api.abc import AbstractCommand
from pyramid.connector.discord.commands.api.annotation import discord_command
from pyramid.connector.discord.commands.api.parameters import ParametersCommand
from pyramid.data.environment import Environment
from pyramid.data.functional.application_info import ApplicationInfo
from pyramid.tools import utils

@discord_command(parameters=ParametersCommand(description="About the bot"))
Expand All @@ -15,6 +18,11 @@ class AboutCommand(AbstractCommand):
# self.__environment = environment
# self.__info = info

def injectService(self, environment: Environment, info: ApplicationInfo):
self.__environment = environment
self.__info = info
# self.logger.info("Injected !")

async def execute(self, ctx: Interaction):
bot_user: ClientUser | None
if self.bot.user is not None:
Expand Down Expand Up @@ -62,7 +70,7 @@ async def execute(self, ctx: Interaction):
)
embed.add_field(
name="Uptime",
value=utils.time_to_duration(int(round(time.time() - self.__started))),
value=utils.time_to_duration(int(round(time.time() - self.__info.get_started_at()))),
inline=True,
)

Expand Down
17 changes: 9 additions & 8 deletions src/pyramid/connector/discord/commands/api/abc.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
from abc import ABC, abstractmethod
import copy
import logging
from abc import ABC, abstractmethod
from typing import Optional
from discord import Interaction
from discord.app_commands import Command
from discord.ext.commands import Bot
from discord.utils import MISSING

from pyramid.connector.discord.commands.api.parameters import ParametersCommand

class AbstractCommand(ABC):

def __init__(self, parameters: ParametersCommand, bot: Bot, logger: logging.Logger):
self.parameters = parameters
self.bot = bot
self.logger = logger
self.parameters = parameters

@abstractmethod
async def execute(self, ctx: Interaction):
pass

def register(self, command_prefix: Optional[str] = None):
if command_prefix is not None:
Expand All @@ -35,3 +29,10 @@ def register(self, command_prefix: Optional[str] = None):
)
# self.bot.tree.add_command(command, guilds=self.parameters.guilds)
self.bot.tree.add_command(command)

def injectService(self):
pass

@abstractmethod
async def execute(self, ctx: Interaction):
pass
4 changes: 2 additions & 2 deletions src/pyramid/connector/discord/commands/api/annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from pyramid.connector.discord.commands.api.abc import AbstractCommand
from pyramid.connector.discord.commands.api.parameters import ParametersCommand
from pyramid.connector.discord.commands.api.register import COMMANDS_AUTOREGISTRED
from pyramid.connector.discord.commands.api.register import COMMANDS_TO_REGISTER


def discord_command(*, parameters: ParametersCommand):
Expand All @@ -23,7 +23,7 @@ def decorator(cls):
parameters.description = '…'
else:
parameters.description = _shorten(cls.__doc__)
COMMANDS_AUTOREGISTRED[cls] = parameters
COMMANDS_TO_REGISTER[cls] = parameters
return cls
return decorator

Expand Down
20 changes: 16 additions & 4 deletions src/pyramid/connector/discord/commands/api/register.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@

import inspect
import logging
from discord.ext.commands import Bot
from pyramid.connector.discord.commands.api.abc import AbstractCommand
from pyramid.connector.discord.commands.api.parameters import ParametersCommand

COMMANDS_AUTOREGISTRED: dict[type[AbstractCommand], ParametersCommand] = {}
COMMANDS_TO_REGISTER: dict[type[AbstractCommand], ParametersCommand] = {}

def register_commands(bot: Bot, logger: logging.Logger, command_prefix: str | None = None):
for cls, parameters in COMMANDS_AUTOREGISTRED.items():
def register_commands(services: dict[str, object], bot: Bot, logger: logging.Logger, command_prefix: str | None = None):
for cls, parameters in COMMANDS_TO_REGISTER.items():
class_instance = cls(parameters, bot, logger)
class_instance.register(command_prefix)
logger.info("%s - %s" % (vars(cls), vars(parameters)))
# logger.info("%s - %s" % (vars(cls), vars(parameters)))
# logger.info("services %s" % ", ".join(services.keys()))

signature = inspect.signature(class_instance.injectService)
params = list(signature.parameters.values())
# for param in params:
# logger.info("param %s" % param.annotation)

# logger.info("params %s" % ", ".join(params))
dependencies = [services[param.annotation.__name__] for param in params]
# logger.info("dependencies %s" % (vars(dependencies)))
class_instance.injectService(*dependencies)
12 changes: 12 additions & 0 deletions src/pyramid/connector/discord/services/api/annotation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from pyramid.connector.discord.services.api.register import SERVICE_TO_REGISTER


def pyramid_service():
def decorator(cls):
# if not issubclass(cls, AbstractService):
# raise TypeError(f"Class {cls.__name__} must extend from AbstractListener")

class_name = cls.__name__
SERVICE_TO_REGISTER[class_name] = cls
return cls
return decorator
13 changes: 13 additions & 0 deletions src/pyramid/connector/discord/services/api/injector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

import logging
from abc import ABC, abstractmethod
from discord.ext.commands import Bot

class ServiceInjector(ABC):

def __init__(self, bot: Bot, logger: logging.Logger):
self.bot = bot
self.logger = logger

def injectService(self):
pass
24 changes: 24 additions & 0 deletions src/pyramid/connector/discord/services/api/register.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import logging
from discord.ext.commands import Bot
from pyramid.connector.discord.services.api.injector import ServiceInjector


SERVICE_TO_REGISTER: dict[str, type[object]] = {}
SERVICE_REGISTRED: dict[str, object] = {}

def register_services(bot: Bot, logger: logging.Logger):
for name, cls in SERVICE_TO_REGISTER.items():
if issubclass(cls, ServiceInjector):
class_instance = cls(bot, logger)
else:
class_instance = cls()
SERVICE_REGISTRED[name] = class_instance
logger.info("SERVICE_REGISTRED %s" % name)

def get_service(name: str):
return SERVICE_REGISTRED[name]

def define_bot(bot: Bot):
for _, instance in SERVICE_REGISTRED.items():
if isinstance(instance, ServiceInjector):
instance.bot = bot
19 changes: 19 additions & 0 deletions src/pyramid/connector/discord/services/environment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

from pyramid.connector.discord.services.api.annotation import pyramid_service
from pyramid.data.environment import Environment


@pyramid_service()
class EnvironmentService:

def __init__(self):
self.__type: Environment = Environment.PRODUCTION

def get_type(self):
return self.__type

def get_type_name(self):
return self.__type.name.capitalize()

def set_type(self, environnement: Environment):
self.__type = environnement
28 changes: 28 additions & 0 deletions src/pyramid/connector/discord/services/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import logging

from pyramid.connector.discord.services.api.annotation import pyramid_service


@pyramid_service()
class LoggerService:

def __init__(self):
self.__logger = logging.getLogger()

def critical(self, msg, *args, **kwargs):
self.__logger.critical(msg, *args, **kwargs)

def error(self, msg, *args, **kwargs):
self.__logger.error(msg, *args, **kwargs)

def warning(self, msg, *args, **kwargs):
self.__logger.warning(msg, *args, **kwargs)

def info(self, msg, *args, **kwargs):
self.__logger.info(msg, *args, **kwargs)

def debug(self, msg, *args, **kwargs):
self.__logger.debug(msg, *args, **kwargs)

def log(self, level, msg, *args, **kwargs):
self.__logger.log(msg, level, *args, **kwargs)
11 changes: 9 additions & 2 deletions src/pyramid/data/functional/application_info.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
import json
import os
import platform
import subprocess
import time

from pyramid.connector.discord.services.api.annotation import pyramid_service


@pyramid_service()
class ApplicationInfo:
def __init__(self):
self.__name = "pyramid"
self.__os = self.__detect_os().lower()
self.__version = os.getenv("PROJECT_VERSION")
self.__started_at = time.time()

def get_name(self):
return self.__name.capitalize()

def get_version(self):
return f"v{self.__version}"
return self.__version

def get_os(self):
return self.__os

def get_started_at(self):
return self.__started_at

def __detect_os(self) -> str:
os_name = platform.system()
if os_name == "Linux":
Expand Down
15 changes: 15 additions & 0 deletions src/pyramid/data/functional/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from datetime import datetime
from threading import Thread

from pyramid.connector.discord.services.api.register import get_service, register_services
from pyramid.connector.discord.services.environment import EnvironmentService
from pyramid.tools import utils
from pyramid.data.functional.application_info import ApplicationInfo
from pyramid.connector.discord.bot import DiscordBot
Expand All @@ -21,6 +23,7 @@ def __init__(self):
# Program information
self._info = ApplicationInfo()
self._health = HealthModules()
self._discord_bot = None

# Argument management
def args(self):
Expand Down Expand Up @@ -89,6 +92,18 @@ def handle_signal(signum: int, frame):
logging.info(f"Received signal {signum}. shutting down ...")
asyncio.run_coroutine_threadsafe(shutdown(loop), loop)

# -- Service [TEMP]
self._discord_bot = discord_bot
if self._discord_bot is None:
raise Exception("Bot is not connected")
register_services(self._discord_bot.bot, self.logger)
environment_service = get_service("EnvironmentService")
self.logger.info("environment_service %s" % environment_service)
if not isinstance(environment_service, EnvironmentService):
raise Exception("environment_service is not from type EnvironmentService, got %s" % type(environment_service))
environment_service.set_type(self._config.mode)
# --

previous_handler = signal.signal(signal.SIGTERM, handle_signal)

# Connect bot to Discord servers in his own thread
Expand Down

0 comments on commit 6536bdb

Please sign in to comment.