Update module interface...

This commit is contained in:
adator85
2025-11-18 16:27:42 +01:00
parent af992f7721
commit 1b30b1ff4e
3 changed files with 59 additions and 85 deletions

View File

@@ -259,20 +259,20 @@ class Base:
self.logs.error(err) self.logs.error(err)
return False 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 core_table = self.Config.TABLE_CONFIG
# Check if the param exist # 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") self.logs.error(f"Le parametre {param_key} n'existe pas dans la variable global")
return False return False
mes_donnees = {'module_name': module_name, 'param_key': param_key, 'param_value': param_value} 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" 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) 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(), mes_donnees = {'datetime': self.Utils.get_sdatetime(),
'module_name': module_name, 'module_name': module_name,
'param_key': param_key, 'param_key': param_key,
@@ -282,14 +282,14 @@ class Base:
update = self.db_execute_query(query, mes_donnees) update = self.db_execute_query(query, mes_donnees)
updated_rows = update.rowcount updated_rows = update.rowcount
if updated_rows > 0: 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}') self.logs.debug(f'Parameter updated : {param_key} - {param_value} | Module: {module_name}')
else: else:
self.logs.error(f'Parameter NOT updated : {param_key} - {param_value} | Module: {module_name}') self.logs.error(f'Parameter NOT updated : {param_key} - {param_value} | Module: {module_name}')
else: else:
self.logs.error(f'Parameter and Module do not exist: Param ({param_key}) - Value ({param_value}) | Module ({module_name})') 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 return True
@@ -362,7 +362,7 @@ class Base:
except Exception as err: except Exception as err:
self.logs.error(err, exc_info=True) 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 """Create a new asynchrone and store it into running_asynctasks variable
Args: Args:

View File

@@ -1,5 +1,5 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Optional from typing import TYPE_CHECKING, Optional, Union
from dataclasses import dataclass from dataclasses import dataclass
if TYPE_CHECKING: if TYPE_CHECKING:
@@ -15,74 +15,38 @@ class IModule(ABC):
def __init__(self, uplink: 'Loader') -> None: def __init__(self, uplink: 'Loader') -> None:
# import the context
self.ctx = uplink
# Module name (Mandatory) # Module name (Mandatory)
self.module_name = 'mod_' + str(self.__class__.__name__).lower() 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 # 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: def init(self) -> None:
self.load() self.load()
self.inspect_class()
self.create_tables() self.create_tables()
# Sync the configuration with core configuration (Mandatory) # 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 return None
def inspect_class(self): def update_configuration(self, param_key: str, param_value: Union[str, int]) -> None:
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:
"""Update the local and core configuration """Update the local and core configuration
Args: Args:
param_key (str): The parameter key param_key (str): The parameter key
param_value (str): The parameter value 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 @abstractmethod
def create_tables(self) -> None: def create_tables(self) -> None:

View File

@@ -1,5 +1,5 @@
import asyncio import asyncio
from typing import Any, TYPE_CHECKING from typing import Any, TYPE_CHECKING, Optional
from core.classes.interfaces.imodule import IModule from core.classes.interfaces.imodule import IModule
from dataclasses import dataclass from dataclasses import dataclass
@@ -28,13 +28,11 @@ class Test(IModule):
def __init__(self, uplink: 'Loader'): def __init__(self, uplink: 'Loader'):
super().__init__(uplink) super().__init__(uplink)
self.init() self._mod_config: Optional[Test.ModConfModel] = None
def create_tables(self) -> None: def create_tables(self) -> None:
"""Methode qui va créer la base de donnée si elle n'existe pas. """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 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: Returns:
None: Aucun retour n'es attendu 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 return None
def load(self) -> None: def load(self) -> None:
@@ -55,18 +53,25 @@ class Test(IModule):
""" """
# Create module commands (Mandatory) # Create module commands (Mandatory)
self.Irc.build_command(0, self.module_name, 'test-command', 'Execute a test command') self.ctx.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.ctx.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.ctx.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.ctx.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(3, self.module_name, 'test_level_3', 'Execute a level 3 test command')
# Build the default configuration model (Mandatory) # 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: def unload(self) -> None:
"""### This method is called when you unload or you reload the module (Mandatory)""" """### This method is called when you unload, or you reload the module (Mandatory)"""
self.Irc.Commands.drop_command_by_module(self.module_name) self.ctx.Irc.Commands.drop_command_by_module(self.module_name)
return None return None
def cmd(self, data: list[str]) -> None: def cmd(self, data: list[str]) -> None:
@@ -79,15 +84,14 @@ class Test(IModule):
try: try:
return None return None
except Exception as err: 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: 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(2)
await asyncio.sleep(3) self.ctx.Logs.debug(f"End of the task: {self.__class__.__name__}")
self.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) """All messages coming from the user commands (Mandatory)
Args: Args:
@@ -96,33 +100,39 @@ class Test(IModule):
cmd (list): The messages coming from the IRCD server. cmd (list): The messages coming from the IRCD server.
fullcmd (list, optional): The full messages coming from the IRCD server. Defaults to []. fullcmd (list, optional): The full messages coming from the IRCD server. Defaults to [].
""" """
u = self.User.get_user(user) u = self.ctx.User.get_user(user)
c = self.Channel.get_channel(channel) if self.Channel.is_valid_channel(channel) else None c = self.ctx.Channel.get_channel(channel) if self.ctx.Channel.is_valid_channel(channel) else None
if u is None: if u is None:
return None return None
command = str(cmd[0]).lower() command = str(cmd[0]).lower()
dnickname = self.Config.SERVICE_NICKNAME dnickname = self.ctx.Config.SERVICE_NICKNAME
match command: match command:
case 'asyncio': case 'asyncio':
task = self.Base.create_asynctask(self.asyncio_func()) self.ctx.Base.create_asynctask(self.asyncio_func())
return None
case 'test-command': case 'test-command':
try: try:
await self.Protocol.send_notice(nick_from=dnickname, nick_to=u.nickname, msg="This is a notice to the sender ...") await self.ctx.Irc.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_priv_msg(nick_from=dnickname, msg=f"This is private message to the sender ...", nick_to=u.nickname)
if c is not None: 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 # How to update your module configuration
self.update_configuration('param_exemple2', 7) self.update_configuration('param_exemple2', 7)
self.update_configuration('param_exemple1', 'my_value') self.update_configuration('param_exemple1', 'my_value')
# Log if you want the result # 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: except Exception as err:
self.Logs.error(f"Unknown Error: {err}") self.ctx.Logs.error(f"Unknown Error: {err}")
return None
case _:
return None