mirror of
https://github.com/iio612/DEFENDER.git
synced 2026-02-13 11:14:23 +00:00
update module management
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import TYPE_CHECKING, Optional
|
from typing import TYPE_CHECKING, Optional
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
from mods.clone.schemas import ModConfModel
|
from mods.clone.schemas import ModConfModel
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@@ -23,6 +22,9 @@ class IModule(ABC):
|
|||||||
# Add Irc Object to the module (Mandatory)
|
# Add Irc Object to the module (Mandatory)
|
||||||
self.Irc = uplink
|
self.Irc = uplink
|
||||||
|
|
||||||
|
# Add Loader object to the module (Mandatory)
|
||||||
|
self.Loader = uplink.Loader
|
||||||
|
|
||||||
# Add Protocol to the module (Mandatory)
|
# Add Protocol to the module (Mandatory)
|
||||||
self.Protocol = uplink.Protocol
|
self.Protocol = uplink.Protocol
|
||||||
|
|
||||||
@@ -41,19 +43,25 @@ class IModule(ABC):
|
|||||||
# Add User object to the module (Mandatory)
|
# Add User object to the module (Mandatory)
|
||||||
self.User = uplink.User
|
self.User = uplink.User
|
||||||
|
|
||||||
|
# Add Client object to the module (Mandatory)
|
||||||
|
self.Client = uplink.Client
|
||||||
|
|
||||||
# Add Channel object to the module (Mandatory)
|
# Add Channel object to the module (Mandatory)
|
||||||
self.Channel = uplink.Channel
|
self.Channel = uplink.Channel
|
||||||
|
|
||||||
# Add Reputation object to the module (Optional)
|
# Add Reputation object to the module (Optional)
|
||||||
self.Reputation = uplink.Reputation
|
self.Reputation = uplink.Reputation
|
||||||
|
|
||||||
self.ModConfig = ModConfModel()
|
# Load the child classes
|
||||||
|
self.load()
|
||||||
|
|
||||||
self.load_module_configuration()
|
# Inspect child classes
|
||||||
"""Load module configuration"""
|
self.inspect_class()
|
||||||
|
|
||||||
|
# Init the ModConfig model object.
|
||||||
|
self.ModConfig:ModConfModel = ModConfModel()
|
||||||
|
|
||||||
self.create_tables()
|
self.create_tables()
|
||||||
"""Create custom module tables"""
|
|
||||||
|
|
||||||
# Sync the configuration with core configuration (Mandatory)
|
# Sync the configuration with core configuration (Mandatory)
|
||||||
uplink.Base.db_sync_core_config(self.module_name, self.ModConfig)
|
uplink.Base.db_sync_core_config(self.module_name, self.ModConfig)
|
||||||
@@ -70,32 +78,27 @@ class IModule(ABC):
|
|||||||
"""
|
"""
|
||||||
self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value)
|
self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value)
|
||||||
|
|
||||||
|
def inspect_class(self):
|
||||||
|
if not hasattr(self, 'ModConfig'):
|
||||||
|
raise AttributeError("The Module must init ModConfig attribute in the load method!")
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
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.
|
"""
|
||||||
Une Session unique pour cette classe sera crée, qui sera utilisé dans cette classe / module
|
Method that will create the database if it does not exist.
|
||||||
|
A single Session for this class will be created, which will be used within this class/module.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
database_name (str): Nom de la base de données ( pas d'espace dans le nom )
|
database_name (str): Name of the database (no spaces allowed in the name)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
None: Aucun retour n'es attendu
|
None: No return is expected
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def load_module_configuration(self) -> None:
|
def load(self) -> None:
|
||||||
"""### Load Module Configuration
|
"""This method is executed when the module is loaded or reloaded.
|
||||||
"""
|
"""
|
||||||
try:
|
|
||||||
# Build the default configuration model (Mandatory)
|
|
||||||
self.ModConfig = self.ModConfModel(jsonrpc=0)
|
|
||||||
|
|
||||||
# Sync the configuration with core configuration (Mandatory)
|
|
||||||
self.Base.db_sync_core_config(self.module_name, self.ModConfig)
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
except TypeError as te:
|
|
||||||
self.Logs.critical(te)
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def unload(self) -> None:
|
def unload(self) -> None:
|
||||||
|
|||||||
@@ -66,9 +66,19 @@ class Module:
|
|||||||
return self.reload_one_module(uplink, module_name, nickname)
|
return self.reload_one_module(uplink, module_name, nickname)
|
||||||
|
|
||||||
# Charger le module
|
# Charger le module
|
||||||
loaded_module = importlib.import_module(f'mods.{module_folder}.{module_name}')
|
try:
|
||||||
my_class = getattr(loaded_module, class_name, None) # Récuperer le nom de classe
|
loaded_module = importlib.import_module(f'mods.{module_folder}.{module_name}')
|
||||||
create_instance_of_the_class = my_class(uplink) # Créer une nouvelle instance de la classe
|
my_class = getattr(loaded_module, class_name, None) # Récuperer le nom de classe
|
||||||
|
create_instance_of_the_class = my_class(uplink) # Créer une nouvelle instance de la classe
|
||||||
|
except AttributeError as attr:
|
||||||
|
red = uplink.Config.COLORS.red
|
||||||
|
nogc = uplink.Config.COLORS.nogc
|
||||||
|
uplink.Protocol.send_priv_msg(
|
||||||
|
nick_from=self.__Config.SERVICE_NICKNAME,
|
||||||
|
msg=f"[{red}MODULE ERROR{nogc}] Module {module_name} is facing issues ! {attr}",
|
||||||
|
channel=self.__Config.SERVICE_CHANLOG
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
if not hasattr(create_instance_of_the_class, 'cmd'):
|
if not hasattr(create_instance_of_the_class, 'cmd'):
|
||||||
uplink.Protocol.send_priv_msg(
|
uplink.Protocol.send_priv_msg(
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
from typing import Optional, TYPE_CHECKING
|
from typing import Optional, TYPE_CHECKING
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from core.classes.interfaces.imodule import IModule
|
||||||
import mods.command.utils as utils
|
import mods.command.utils as utils
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from core.irc import Irc
|
|
||||||
from core.definition import MUser
|
from core.definition import MUser
|
||||||
from sqlalchemy import CursorResult, Row, Sequence
|
|
||||||
|
|
||||||
class Command:
|
class Command(IModule):
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ModConfModel:
|
class ModConfModel:
|
||||||
@@ -15,44 +14,44 @@ class Command:
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def __init__(self, ircInstance: 'Irc') -> 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 )
|
||||||
|
|
||||||
# Module name (Mandatory)
|
Returns:
|
||||||
self.module_name = 'mod_' + str(self.__class__.__name__).lower()
|
None: Aucun retour n'es attendu
|
||||||
|
"""
|
||||||
|
|
||||||
# Add Irc Object to the module (Mandatory)
|
table_automode = '''CREATE TABLE IF NOT EXISTS command_automode (
|
||||||
self.Irc = ircInstance
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
created_on TEXT,
|
||||||
|
updated_on TEXT,
|
||||||
|
nickname TEXT,
|
||||||
|
channel TEXT,
|
||||||
|
mode TEXT
|
||||||
|
)
|
||||||
|
'''
|
||||||
|
|
||||||
# Add Loader Object to the module (Mandatory)
|
self.Base.db_execute_query(table_automode)
|
||||||
self.Loader = ircInstance.Loader
|
return None
|
||||||
|
|
||||||
# Add Protocol object to the module (Mandatory)
|
|
||||||
self.Protocol = ircInstance.Protocol
|
|
||||||
|
|
||||||
# Add Global Configuration to the module (Mandatory)
|
|
||||||
self.Config = ircInstance.Config
|
|
||||||
|
|
||||||
# Add Base object to the module (Mandatory)
|
|
||||||
self.Base = ircInstance.Base
|
|
||||||
|
|
||||||
# Add main Utils to the module
|
|
||||||
self.MainUtils = ircInstance.Utils
|
|
||||||
|
|
||||||
# Add logs object to the module (Mandatory)
|
|
||||||
self.Logs = ircInstance.Loader.Logs
|
|
||||||
|
|
||||||
# Add User object to the module (Mandatory)
|
|
||||||
self.User = ircInstance.User
|
|
||||||
|
|
||||||
# Add Client object to the module (Mandatory)
|
|
||||||
self.Client = ircInstance.Client
|
|
||||||
|
|
||||||
# Add Channel object to the module (Mandatory)
|
|
||||||
self.Channel = ircInstance.Channel
|
|
||||||
|
|
||||||
|
def load(self) -> None:
|
||||||
# Module Utils
|
# Module Utils
|
||||||
self.mod_utils = utils
|
self.mod_utils = utils
|
||||||
|
|
||||||
|
# Build the default configuration model (Mandatory)
|
||||||
|
self.ModConfig = self.ModConfModel()
|
||||||
|
|
||||||
|
self.user_to_notice: str = ''
|
||||||
|
self.show_219: bool = True
|
||||||
|
|
||||||
|
# Register new commands into the protocol
|
||||||
|
new_cmds = {'403', '401', '006', '018', '219', '223'}
|
||||||
|
for c in new_cmds:
|
||||||
|
self.Irc.Protocol.known_protocol.add(c)
|
||||||
|
|
||||||
self.Irc.build_command(2, self.module_name, 'join', 'Join a channel')
|
self.Irc.build_command(2, self.module_name, 'join', 'Join a channel')
|
||||||
self.Irc.build_command(2, self.module_name, 'assign', 'Assign a user to a role or task')
|
self.Irc.build_command(2, self.module_name, 'assign', 'Assign a user to a role or task')
|
||||||
self.Irc.build_command(2, self.module_name, 'part', 'Leave a channel')
|
self.Irc.build_command(2, self.module_name, 'part', 'Leave a channel')
|
||||||
@@ -104,73 +103,6 @@ class Command:
|
|||||||
self.Irc.build_command(2, self.module_name, 'klinelist', 'List all K-line bans')
|
self.Irc.build_command(2, self.module_name, 'klinelist', 'List all K-line bans')
|
||||||
self.Irc.build_command(3, self.module_name, 'map', 'Show the server network map')
|
self.Irc.build_command(3, self.module_name, 'map', 'Show the server network map')
|
||||||
|
|
||||||
# Init the module
|
|
||||||
self.__init_module()
|
|
||||||
|
|
||||||
# Log the module
|
|
||||||
self.Logs.debug(f'-- Module {self.module_name} loaded ...')
|
|
||||||
|
|
||||||
def __init_module(self) -> None:
|
|
||||||
|
|
||||||
# Create you own tables (Mandatory)
|
|
||||||
self.__create_tables()
|
|
||||||
|
|
||||||
# Load module configuration and sync with core one (Mandatory)
|
|
||||||
self.__load_module_configuration()
|
|
||||||
# End of mandatory methods you can start your customization #
|
|
||||||
|
|
||||||
self.user_to_notice: str = ''
|
|
||||||
self.show_219: bool = True
|
|
||||||
|
|
||||||
return 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
|
|
||||||
"""
|
|
||||||
|
|
||||||
table_automode = '''CREATE TABLE IF NOT EXISTS command_automode (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
created_on TEXT,
|
|
||||||
updated_on TEXT,
|
|
||||||
nickname TEXT,
|
|
||||||
channel TEXT,
|
|
||||||
mode TEXT
|
|
||||||
)
|
|
||||||
'''
|
|
||||||
|
|
||||||
self.Base.db_execute_query(table_automode)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def __load_module_configuration(self) -> None:
|
|
||||||
"""### Load Module Configuration
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# Build the default configuration model (Mandatory)
|
|
||||||
self.ModConfig = self.ModConfModel()
|
|
||||||
|
|
||||||
# Sync the configuration with core configuration (Mandatory)
|
|
||||||
self.Base.db_sync_core_config(self.module_name, self.ModConfig)
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
except TypeError as te:
|
|
||||||
self.Logs.critical(te)
|
|
||||||
|
|
||||||
def __update_configuration(self, param_key: str, param_value: str):
|
|
||||||
"""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)
|
|
||||||
|
|
||||||
def unload(self) -> None:
|
def unload(self) -> None:
|
||||||
self.Irc.Commands.drop_command_by_module(self.module_name)
|
self.Irc.Commands.drop_command_by_module(self.module_name)
|
||||||
return None
|
return None
|
||||||
@@ -186,10 +118,12 @@ class Command:
|
|||||||
nogc = self.Config.COLORS.nogc
|
nogc = self.Config.COLORS.nogc
|
||||||
cmd = list(data).copy()
|
cmd = list(data).copy()
|
||||||
|
|
||||||
if len(cmd) < 2:
|
pos, parsed_cmd = self.Irc.Protocol.get_ircd_protocol_poisition(cmd=cmd, log=True)
|
||||||
|
|
||||||
|
if pos == -1:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
match cmd[1]:
|
match parsed_cmd:
|
||||||
# [':irc.deb.biz.st', '403', 'Dev-PyDefender', '#Z', ':No', 'such', 'channel']
|
# [':irc.deb.biz.st', '403', 'Dev-PyDefender', '#Z', ':No', 'such', 'channel']
|
||||||
case '403' | '401':
|
case '403' | '401':
|
||||||
try:
|
try:
|
||||||
@@ -260,22 +194,10 @@ class Command:
|
|||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.Logs.warning(f'Unknown Error: {str(err)}')
|
self.Logs.warning(f'Unknown Error: {str(err)}')
|
||||||
|
|
||||||
case _:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if len(cmd) < 3:
|
|
||||||
return None
|
|
||||||
|
|
||||||
match cmd[2]:
|
|
||||||
|
|
||||||
case 'SJOIN':
|
case 'SJOIN':
|
||||||
# ['@msgid=yldTlbwAGbzCGUcCIHi3ku;time=2024-11-11T17:56:24.297Z', ':001', 'SJOIN', '1728815963', '#znc', ':001LQ0L0C']
|
# ['@msgid=yldTlbwAGbzCGUcCIHi3ku;time=2024-11-11T17:56:24.297Z', ':001', 'SJOIN', '1728815963', '#znc', ':001LQ0L0C']
|
||||||
# Check if the user has an automode
|
# Check if the user has an automode
|
||||||
try:
|
try:
|
||||||
|
|
||||||
if len(cmd) < 6:
|
|
||||||
return None
|
|
||||||
|
|
||||||
user_uid = self.User.clean_uid(cmd[5])
|
user_uid = self.User.clean_uid(cmd[5])
|
||||||
userObj: MUser = self.User.get_user(user_uid)
|
userObj: MUser = self.User.get_user(user_uid)
|
||||||
channel_name = cmd[4] if self.Channel.is_valid_channel(cmd[4]) else None
|
channel_name = cmd[4] if self.Channel.is_valid_channel(cmd[4]) else None
|
||||||
@@ -301,6 +223,9 @@ class Command:
|
|||||||
except KeyError as ke:
|
except KeyError as ke:
|
||||||
self.Logs.error(f"Key Error: {err}")
|
self.Logs.error(f"Key Error: {err}")
|
||||||
|
|
||||||
|
case _:
|
||||||
|
pass
|
||||||
|
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.Logs.error(f"General Error: {err}")
|
self.Logs.error(f"General Error: {err}")
|
||||||
|
|
||||||
|
|||||||
@@ -6,25 +6,12 @@ class Test(IModule):
|
|||||||
@dataclass
|
@dataclass
|
||||||
class ModConfModel:
|
class ModConfModel:
|
||||||
"""The Model containing the module parameters
|
"""The Model containing the module parameters
|
||||||
|
you can leave it without params.
|
||||||
|
just use pass | if you leave it empty, in the load() method just init empty object ==> self.ModConfig = ModConfModel()
|
||||||
"""
|
"""
|
||||||
param_exemple1: str
|
param_exemple1: str
|
||||||
param_exemple2: int
|
param_exemple2: int
|
||||||
|
|
||||||
def load_module_configuration(self) -> None:
|
|
||||||
"""### Load Module Configuration
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Create module commands (Mandatory)
|
|
||||||
self.Irc.build_command(0, self.module_name, 'test-command', 'Execute a test command')
|
|
||||||
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')
|
|
||||||
|
|
||||||
# Build the default configuration model (Mandatory)
|
|
||||||
self.ModConfig = self.ModConfModel(param_exemple1='str', param_exemple2=1)
|
|
||||||
|
|
||||||
return 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
|
||||||
@@ -45,6 +32,19 @@ class Test(IModule):
|
|||||||
# self.Base.db_execute_query(table_logs)
|
# self.Base.db_execute_query(table_logs)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def load(self) -> None:
|
||||||
|
"""### Load Module Configuration
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Create module commands (Mandatory)
|
||||||
|
self.Irc.build_command(0, self.module_name, 'test-command', 'Execute a test command')
|
||||||
|
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')
|
||||||
|
|
||||||
|
# Build the default configuration model (Mandatory)
|
||||||
|
self.ModConfig = self.ModConfModel(param_exemple1='str', param_exemple2=1)
|
||||||
|
|
||||||
def unload(self) -> None:
|
def unload(self) -> None:
|
||||||
self.Irc.Commands.drop_command_by_module(self.module_name)
|
self.Irc.Commands.drop_command_by_module(self.module_name)
|
||||||
return None
|
return None
|
||||||
|
|||||||
Reference in New Issue
Block a user