diff options
| author | 2023-07-30 13:46:16 +0800 | |
|---|---|---|
| committer | 2023-07-30 13:46:16 +0800 | |
| commit | 0b71a030e3cc5cf9f02491e0839bebebc5723ec6 (patch) | |
| tree | 24e7398722cb4861fa966b9849609a14b4a6bb72 /HydroRollCore | |
| parent | 4d6945488f6ddc052b02eeef3075faf00a9481d7 (diff) | |
| download | infini-0b71a030e3cc5cf9f02491e0839bebebc5723ec6.tar.gz infini-0b71a030e3cc5cf9f02491e0839bebebc5723ec6.zip | |
feat: 添加泛型
Diffstat (limited to 'HydroRollCore')
| -rw-r--r-- | HydroRollCore/__init__.py | 2 | ||||
| -rw-r--r-- | HydroRollCore/cli.py (renamed from HydroRollCore/main.py) | 0 | ||||
| -rw-r--r-- | HydroRollCore/config.py | 0 | ||||
| -rw-r--r-- | HydroRollCore/exception.py | 0 | ||||
| -rw-r--r-- | HydroRollCore/log.py | 0 | ||||
| -rw-r--r-- | HydroRollCore/rule.py | 141 | ||||
| -rw-r--r-- | HydroRollCore/typing.py | 0 | ||||
| -rw-r--r-- | HydroRollCore/utils.py | 0 |
8 files changed, 113 insertions, 30 deletions
diff --git a/HydroRollCore/__init__.py b/HydroRollCore/__init__.py index 7c90048d..7133a630 100644 --- a/HydroRollCore/__init__.py +++ b/HydroRollCore/__init__.py @@ -1,3 +1,5 @@ name = "HydroRollCore" from HydroRollCore.rule import Rule + +__all__ = ['Rule']
\ No newline at end of file diff --git a/HydroRollCore/main.py b/HydroRollCore/cli.py index ba128384..ba128384 100644 --- a/HydroRollCore/main.py +++ b/HydroRollCore/cli.py diff --git a/HydroRollCore/config.py b/HydroRollCore/config.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/HydroRollCore/config.py diff --git a/HydroRollCore/exception.py b/HydroRollCore/exception.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/HydroRollCore/exception.py diff --git a/HydroRollCore/log.py b/HydroRollCore/log.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/HydroRollCore/log.py diff --git a/HydroRollCore/rule.py b/HydroRollCore/rule.py index bdc24369..8a72c8c6 100644 --- a/HydroRollCore/rule.py +++ b/HydroRollCore/rule.py @@ -1,30 +1,111 @@ -import os -import importlib.util - -__all__ = ["Rule"] - -class Rule: - def __init__(self, folder_path): - self.folder_path = folder_path - - def load_modules(self): - # 获取指定文件夹下的所有文件和文件夹 - file_list = os.listdir(self.folder_path) - module_list = [] - - # 遍历文件列表 - for file_name in file_list: - file_path = os.path.join(self.folder_path, file_name) - - # 判断是否为Python文件或者包 - if file_name.startswith('_') or not file_name.endswith(".py"): - continue - - # 尝试加载模块 - module_name = os.path.splitext(file_name)[0] - spec = importlib.util.spec_from_file_location(module_name, file_path) - module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - module_list.append(module) - - return module_list +"""iamai 插件。 + +所有 iamai 插件的基类。所有用户编写的插件必须继承自 `Plugin` 类。 +""" +from enum import Enum +from abc import ABC, abstractmethod +from typing import TYPE_CHECKING, Type, Generic, NoReturn, Optional + +from hydrorollcore.config import ConfigModel +from hydrorollcore.utils import is_config_class +from hydrorollcore.typing import T_Event, T_State, T_Config +from hydrorollcore.exceptions import SkipException, StopException + +if TYPE_CHECKING: + from iamai.bot import Bot + +__all__ = ["Rule", "RuleLoadType"] + + +class RuleLoadType(Enum): + """插件加载类型。""" + + DIR = "dir" + NAME = "name" + FILE = "file" + CLASS = "class" + + +class Rule(ABC, Generic[T_Event, T_State, T_Config]): + """所有 iamai 插件的基类。 + + Attributes: + event: 当前正在被此插件处理的事件。 + priority: 插件的优先级,数字越小表示优先级越高,默认为 0。 + block: 插件执行结束后是否阻止事件的传播。True 表示阻止。 + __plugin_load_type__: 插件加载类型,由 iamai 自动设置,反映了此插件是如何被加载的。 + __plugin_file_path__: 当插件加载类型为 `PluginLoadType.CLASS` 时为 `None`, + 否则为定义插件在的 Python 模块的位置。 + """ + + event: T_Event + priority: int = 0 + block: bool = False + Config: Type[ConfigModel] + + __plugin_load_type__: PluginLoadType + __plugin_file_path__: Optional[str] + + def __init__(self, event: T_Event): + self.event = event + + if not hasattr(self, "priority"): + self.priority = 0 + if not hasattr(self, "block"): + self.block = False + + self.get = self.bot.get + + self.__post_init__() + + def __post_init__(self): + """用于初始化后处理,被 `__init__()` 方法调用。""" + pass + + @property + def name(self) -> str: + """插件类名称。""" + return self.__class__.__name__ + + @property + def bot(self) -> "Bot": + """机器人对象。""" + return self.event.adapter.bot + + @property + def config(self) -> Optional[T_Config]: + """插件配置。""" + config_class: ConfigModel = getattr(self, "Config", None) + if is_config_class(config_class): + return getattr(self.bot.config.plugin, config_class.__config_name__, None) + return None + + def stop(self) -> NoReturn: + """停止当前事件传播。""" + raise StopException() + + def skip(self) -> NoReturn: + """跳过自身继续当前事件传播。""" + raise SkipException() + + @property + def state(self) -> T_State: + """插件状态。""" + return self.bot.plugin_state[self.name] + + @state.setter + def state(self, value: T_State): + self.bot.plugin_state[self.name] = value + + @abstractmethod + async def handle(self) -> None: + """处理事件的方法。当 `rule()` 方法返回 `True` 时 iamai 会调用此方法。每个插件必须实现此方法。""" + raise NotImplementedError + + @abstractmethod + async def rule(self) -> bool: + """匹配事件的方法。事件处理时,会按照插件的优先级依次调用此方法,当此方法返回 `True` 时将事件交由此插件处理。每个插件必须实现此方法。 + + 注意:不建议直接在此方法内实现对事件的处理,事件的具体处理请交由 `handle()` 方法。 + """ + raise NotImplementedError
\ No newline at end of file diff --git a/HydroRollCore/typing.py b/HydroRollCore/typing.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/HydroRollCore/typing.py diff --git a/HydroRollCore/utils.py b/HydroRollCore/utils.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/HydroRollCore/utils.py |
