diff --git a/core/base.py b/core/base.py index 474050b..dff0d0e 100644 --- a/core/base.py +++ b/core/base.py @@ -259,20 +259,20 @@ class Base: self.logs.error(err) return False - def db_update_core_config(self, module_name:str, dataclassObj: object, param_key:str, param_value: str) -> bool: + def db_update_core_config(self, module_name:str, dataclass_obj: object, param_key:str, param_value: str) -> bool: core_table = self.Config.TABLE_CONFIG # Check if the param exist - if not hasattr(dataclassObj, param_key): + if not hasattr(dataclass_obj, param_key): self.logs.error(f"Le parametre {param_key} n'existe pas dans la variable global") return False mes_donnees = {'module_name': module_name, 'param_key': param_key, 'param_value': param_value} search_param_query = f"SELECT id FROM {core_table} WHERE module_name = :module_name AND param_key = :param_key" result = self.db_execute_query(search_param_query, mes_donnees) - isParamExist = result.fetchone() + is_param_exist = result.fetchone() - if not isParamExist is None: + if not is_param_exist is None: mes_donnees = {'datetime': self.Utils.get_sdatetime(), 'module_name': module_name, 'param_key': param_key, @@ -282,14 +282,14 @@ class Base: update = self.db_execute_query(query, mes_donnees) updated_rows = update.rowcount if updated_rows > 0: - setattr(dataclassObj, param_key, self.int_if_possible(param_value)) + setattr(dataclass_obj, param_key, self.int_if_possible(param_value)) self.logs.debug(f'Parameter updated : {param_key} - {param_value} | Module: {module_name}') else: self.logs.error(f'Parameter NOT updated : {param_key} - {param_value} | Module: {module_name}') else: self.logs.error(f'Parameter and Module do not exist: Param ({param_key}) - Value ({param_value}) | Module ({module_name})') - self.logs.debug(dataclassObj) + self.logs.debug(dataclass_obj) return True @@ -362,7 +362,7 @@ class Base: except Exception as err: self.logs.error(err, exc_info=True) - def create_asynctask(self, func: Callable, *, async_name: str = None, run_once: bool = False) -> asyncio.Task: + def create_asynctask(self, func: Any, *, async_name: str = None, run_once: bool = False) -> asyncio.Task: """Create a new asynchrone and store it into running_asynctasks variable Args: diff --git a/core/classes/interfaces/imodule.py b/core/classes/interfaces/imodule.py index fa22f52..309b853 100644 --- a/core/classes/interfaces/imodule.py +++ b/core/classes/interfaces/imodule.py @@ -1,5 +1,5 @@ from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING, Optional, Union from dataclasses import dataclass if TYPE_CHECKING: @@ -15,74 +15,38 @@ class IModule(ABC): def __init__(self, uplink: 'Loader') -> None: + # import the context + self.ctx = uplink + # Module name (Mandatory) self.module_name = 'mod_' + str(self.__class__.__name__).lower() - # Add Irc Object to the module (Mandatory) - self.Irc = uplink.Irc - - # Add Loader object to the module (Mandatory) - self.Loader = uplink - - # Add Protocol to the module (Mandatory) - self.Protocol = uplink.Irc.Protocol - - # Add Global Configuration to the module (Mandatory) - self.Config = uplink.Config - - # Add Settings to the module (Mandatory) - self.Settings = uplink.Settings - - # Add Base object to the module (Mandatory) - self.Base = uplink.Base - - # Add Main Utils (Mandatory) - self.MainUtils = uplink.Utils - - # Add logs object to the module (Mandatory) - self.Logs = uplink.Logs - - # Add User object to the module (Mandatory) - self.User = uplink.User - - # Add Client object to the module (Mandatory) - self.Client = uplink.Client - - # Add Admin object to the module (Mandatory) - self.Admin = uplink.Admin - - # Add Channel object to the module (Mandatory) - self.Channel = uplink.Channel - - # Add Reputation object to the module (Optional) - self.Reputation = uplink.Reputation - # Log the module - self.Logs.debug(f'Loading Module {self.module_name} ...') + self.ctx.Logs.debug(f'Loading Module {self.module_name} ...') def init(self) -> None: self.load() - self.inspect_class() self.create_tables() # Sync the configuration with core configuration (Mandatory) - self.Base.db_sync_core_config(self.module_name, self.ModConfig) + self.ctx.Base.db_sync_core_config(self.module_name, self.mod_config) return None - def inspect_class(self): - if not hasattr(self, 'ModConfig'): - raise AttributeError("The Module must init ModConfig attribute in the load method!") - if not hasattr(self, 'MOD_HEADER'): - raise NotImplementedError(f"You must declare the header of the module in {self.__class__.__name__}!") - - def update_configuration(self, param_key: str, param_value: str) -> None: + def update_configuration(self, param_key: str, param_value: Union[str, int]) -> None: """Update the local and core configuration Args: param_key (str): The parameter key param_value (str): The parameter value """ - self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value) + self.ctx.Base.db_update_core_config(self.module_name, self.mod_config, param_key, param_value) + + @property + @abstractmethod + def mod_config(self) -> ModConfModel: + """ + The module configuration model + """ @abstractmethod def create_tables(self) -> None: diff --git a/mods/test/mod_test.py b/mods/test/mod_test.py index 0425279..4b8aac7 100644 --- a/mods/test/mod_test.py +++ b/mods/test/mod_test.py @@ -1,5 +1,5 @@ import asyncio -from typing import Any, TYPE_CHECKING +from typing import Any, TYPE_CHECKING, Optional from core.classes.interfaces.imodule import IModule from dataclasses import dataclass @@ -28,13 +28,11 @@ class Test(IModule): def __init__(self, uplink: 'Loader'): super().__init__(uplink) - self.init() + self._mod_config: Optional[Test.ModConfModel] = None def create_tables(self) -> None: """Methode qui va créer la base de donnée si elle n'existe pas. Une Session unique pour cette classe sera crée, qui sera utilisé dans cette classe / module - Args: - database_name (str): Nom de la base de données ( pas d'espace dans le nom ) Returns: None: Aucun retour n'es attendu @@ -47,7 +45,7 @@ class Test(IModule): ) ''' - # self.Base.db_execute_query(table_logs) + # self.ctx.Base.db_execute_query(table_logs) return None def load(self) -> None: @@ -55,18 +53,25 @@ class Test(IModule): """ # Create module commands (Mandatory) - self.Irc.build_command(0, self.module_name, 'test-command', 'Execute a test command') - self.Irc.build_command(0, self.module_name, 'asyncio', 'Create a new asynchron task!') - self.Irc.build_command(1, self.module_name, 'test_level_1', 'Execute a level 1 test command') - self.Irc.build_command(2, self.module_name, 'test_level_2', 'Execute a level 2 test command') - self.Irc.build_command(3, self.module_name, 'test_level_3', 'Execute a level 3 test command') + self.ctx.Irc.build_command(0, self.module_name, 'test-command', 'Execute a test command') + self.ctx.Irc.build_command(0, self.module_name, 'asyncio', 'Create a new asynchron task!') + self.ctx.Irc.build_command(1, self.module_name, 'test_level_1', 'Execute a level 1 test command') + self.ctx.Irc.build_command(2, self.module_name, 'test_level_2', 'Execute a level 2 test command') + self.ctx.Irc.build_command(3, self.module_name, 'test_level_3', 'Execute a level 3 test command') # Build the default configuration model (Mandatory) - self.ModConfig = self.ModConfModel(param_exemple1='str', param_exemple2=1) + self._mod_config = self.ModConfModel(param_exemple1='str', param_exemple2=1) + + # Init the module (Mandatory) + self.init() + + @property + def mod_config(self) -> ModConfModel: + return self._mod_config def unload(self) -> None: - """### This method is called when you unload or you reload the module (Mandatory)""" - self.Irc.Commands.drop_command_by_module(self.module_name) + """### This method is called when you unload, or you reload the module (Mandatory)""" + self.ctx.Irc.Commands.drop_command_by_module(self.module_name) return None def cmd(self, data: list[str]) -> None: @@ -79,15 +84,14 @@ class Test(IModule): try: return None except Exception as err: - self.Logs.error(f"General Error: {err}") + self.ctx.Logs.error(f"General Error: {err}") async def asyncio_func(self) -> None: - self.Logs.debug(f"Starting async method in a task: {self.__class__.__name__}") + self.ctx.Logs.debug(f"Starting async method in a task: {self.__class__.__name__}") await asyncio.sleep(2) - await asyncio.sleep(3) - self.Logs.debug(f"End of the task: {self.__class__.__name__}") + self.ctx.Logs.debug(f"End of the task: {self.__class__.__name__}") - async def hcmds(self, user: str, channel: Any, cmd: list, fullcmd: list = []) -> None: + async def hcmds(self, user: str, channel: Any, cmd: list, fullcmd: Optional[list] = None) -> None: """All messages coming from the user commands (Mandatory) Args: @@ -96,33 +100,39 @@ class Test(IModule): cmd (list): The messages coming from the IRCD server. fullcmd (list, optional): The full messages coming from the IRCD server. Defaults to []. """ - u = self.User.get_user(user) - c = self.Channel.get_channel(channel) if self.Channel.is_valid_channel(channel) else None + u = self.ctx.User.get_user(user) + c = self.ctx.Channel.get_channel(channel) if self.ctx.Channel.is_valid_channel(channel) else None if u is None: return None command = str(cmd[0]).lower() - dnickname = self.Config.SERVICE_NICKNAME + dnickname = self.ctx.Config.SERVICE_NICKNAME match command: case 'asyncio': - task = self.Base.create_asynctask(self.asyncio_func()) + self.ctx.Base.create_asynctask(self.asyncio_func()) + return None case 'test-command': try: - await self.Protocol.send_notice(nick_from=dnickname, nick_to=u.nickname, msg="This is a notice to the sender ...") - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"This is private message to the sender ...", nick_to=u.nickname) + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=u.nickname, msg="This is a notice to the sender ...") + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"This is private message to the sender ...", nick_to=u.nickname) if c is not None: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"This is private message to the sender ...", channel=c.name) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"This is private message to the sender ...", channel=c.name) # How to update your module configuration self.update_configuration('param_exemple2', 7) self.update_configuration('param_exemple1', 'my_value') # Log if you want the result - self.Logs.debug(f"Test logs ready") + self.ctx.Logs.debug(f"Test logs ready") + return None except Exception as err: - self.Logs.error(f"Unknown Error: {err}") \ No newline at end of file + self.ctx.Logs.error(f"Unknown Error: {err}") + return None + + case _: + return None \ No newline at end of file