Added libs
This commit is contained in:
97
noSys/modules.py
Normal file
97
noSys/modules.py
Normal file
@@ -0,0 +1,97 @@
|
||||
from typing import TYPE_CHECKING
|
||||
if TYPE_CHECKING:
|
||||
from .noSysCore import NoSysCore
|
||||
|
||||
import sys
|
||||
import importlib
|
||||
import logging
|
||||
from typing import Dict, Tuple, Any
|
||||
|
||||
from .events import Events
|
||||
from .noSysModule import NoSysModule
|
||||
from libs.app.common.logging import get_logger
|
||||
from libs.fspn.protocol.security import Pmc
|
||||
|
||||
logger = get_logger("moduleManager", buffer=True)
|
||||
|
||||
class ModuleManager:
|
||||
"""Loads, unloads, and manages modules dynamically."""
|
||||
|
||||
def __init__(self, nosys_core: "NoSysCore"):
|
||||
self.nosys_core = nosys_core
|
||||
self.modules: Dict[str, NoSysModule] = {}
|
||||
from libs.api.api import Api
|
||||
self.api:Api = None
|
||||
self.pmc:Pmc = None
|
||||
|
||||
self.load_from_config()
|
||||
|
||||
def get(self, package_id, module_id) -> NoSysModule:
|
||||
return self.modules.get((package_id, module_id))
|
||||
|
||||
def load_from_config(self):
|
||||
libs = self.nosys_core.config.get("app", "libs")
|
||||
for lib in libs:
|
||||
if lib.get("enabled", True):
|
||||
for module in self.nosys_core.config.get(lib.get("id"), "info", "modules"):
|
||||
self.load(lib.get("id"), module.get("id"))
|
||||
|
||||
def load(self, package_id: str, module_id: str):
|
||||
"""Dynamically load a module and initialize it."""
|
||||
logger.debug(f"Importing module: {package_id}.{module_id}")
|
||||
|
||||
key = (package_id, module_id)
|
||||
if key in self.modules:
|
||||
return self.modules[key]
|
||||
|
||||
path = f"libs.{package_id}.{module_id}"
|
||||
|
||||
try:
|
||||
if path in sys.modules:
|
||||
module = importlib.reload(sys.modules[path])
|
||||
else:
|
||||
module = importlib.import_module(path)
|
||||
|
||||
# Prefer explicit "get_module_class" function if provided
|
||||
if hasattr(module, "get_module_class"):
|
||||
clss = module.get_module_class()
|
||||
else:
|
||||
# Fallback to naming convention: Uppercase the first letter of the module
|
||||
class_name = module_id[:1].upper()+module_id[1:]
|
||||
clss = getattr(module, class_name)
|
||||
|
||||
if not issubclass(clss, NoSysModule):
|
||||
raise TypeError(f"{clss} must inherit from NoSysModule")
|
||||
|
||||
instance = clss(self.nosys_core)
|
||||
self.modules[key] = instance
|
||||
|
||||
logger.debug(f"Module loaded: {path} ({clss.__name__})")
|
||||
return instance
|
||||
except Exception as e:
|
||||
logger.exception(f"Failed to load module {path}: {e}")
|
||||
return None
|
||||
|
||||
def unload(self, package_id: str, module_id: str):
|
||||
"""Unload a module and call its teardown hook if available."""
|
||||
key = (package_id, module_id)
|
||||
if key not in self.modules:
|
||||
return
|
||||
|
||||
module:NoSysModule = self.modules.pop(key)
|
||||
|
||||
try:
|
||||
module.teardown_module()
|
||||
except Exception as e:
|
||||
logger.warning(f"Error during teardown of {key}: {e}")
|
||||
|
||||
logger.debug(f"Module unloaded: {key}")
|
||||
|
||||
def reload(self, package_id: str, module_id: str):
|
||||
"""Reload a module (unload + load)."""
|
||||
self.unload(package_id, module_id)
|
||||
return self.load(package_id, module_id)
|
||||
|
||||
def setup(self):
|
||||
for module in self.modules.values():
|
||||
module.setup()
|
||||
Reference in New Issue
Block a user