aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tests
diff options
context:
space:
mode:
author简律纯 <hsiangnianian@outlook.com>2023-04-23 23:36:31 +0800
committer简律纯 <hsiangnianian@outlook.com>2023-04-23 23:36:31 +0800
commit3c12e0e8d51699abeebb822414cf1ef3cc126f26 (patch)
treeef22f40ca380eb6bb374c0cf6b9209c5e68297c8 /tests
parent10289094f39b0794ebc3d4c9a901ebb16adab1fc (diff)
downloadHydroRoll-3c12e0e8d51699abeebb822414cf1ef3cc126f26.tar.gz
HydroRoll-3c12e0e8d51699abeebb822414cf1ef3cc126f26.zip
✨fix
Diffstat (limited to 'tests')
-rw-r--r--tests/config.toml28
-rw-r--r--tests/data/bot_info.json3
-rw-r--r--tests/data/reply_data.json17
-rw-r--r--tests/main.py6
-rw-r--r--tests/plugins/iamai_plugin_base/__init__.py85
-rw-r--r--tests/plugins/iamai_plugin_base/config.py30
-rw-r--r--tests/plugins/iamai_plugin_reply/__init__.py43
-rw-r--r--tests/plugins/iamai_plugin_reply/config.py11
8 files changed, 223 insertions, 0 deletions
diff --git a/tests/config.toml b/tests/config.toml
new file mode 100644
index 0000000..55d49a5
--- /dev/null
+++ b/tests/config.toml
@@ -0,0 +1,28 @@
+[HydroRoll]
+version = "v0.1.0"
+svn = "1"
+author = "简律纯"
+
+[HydroRoll.self]
+header = "Hydro系[1]号"
+# info = "一只水系骰子..."
+
+
+[bot]
+plugins = []
+plugin_dirs = ["plugins"]
+adapters = ["iamai.adapter.cqhttp","iamai.adapter.apscheduler"]
+
+[bot.log]
+level = "INFO"
+verbose_exception = true
+
+[adapter.cqhttp]
+adapter_type = "reverse-ws"
+host = "127.0.0.1"
+port = 8080
+url = "/cqhttp/ws"
+show_raw = false
+
+[adapter.apscheduler]
+scheduler_config = { "apscheduler.timezone" = "Asia/Shanghai" } \ No newline at end of file
diff --git a/tests/data/bot_info.json b/tests/data/bot_info.json
new file mode 100644
index 0000000..7890022
--- /dev/null
+++ b/tests/data/bot_info.json
@@ -0,0 +1,3 @@
+{
+ nick : "本大魔王"
+} \ No newline at end of file
diff --git a/tests/data/reply_data.json b/tests/data/reply_data.json
new file mode 100644
index 0000000..e4977ee
--- /dev/null
+++ b/tests/data/reply_data.json
@@ -0,0 +1,17 @@
+[
+ {
+ "rule": "hello",
+ "message": "你好!"
+ },
+ {
+ "rule": "test",
+ "message": [
+ {
+ "type": "text",
+ "data": {
+ "text": "测试"
+ }
+ }
+ ]
+ }
+] \ No newline at end of file
diff --git a/tests/main.py b/tests/main.py
new file mode 100644
index 0000000..93f67f2
--- /dev/null
+++ b/tests/main.py
@@ -0,0 +1,6 @@
+from HydroRoll import Bot
+
+bot = Bot(hot_reload=True)
+
+if __name__ == "__main__":
+ bot.run()
diff --git a/tests/plugins/iamai_plugin_base/__init__.py b/tests/plugins/iamai_plugin_base/__init__.py
new file mode 100644
index 0000000..8fe559b
--- /dev/null
+++ b/tests/plugins/iamai_plugin_base/__init__.py
@@ -0,0 +1,85 @@
+import re
+from abc import ABC, abstractmethod
+from typing import Type, Union, Generic, TypeVar
+
+from iamai import Plugin
+from iamai.typing import T_State
+from iamai.adapter.cqhttp.event import GroupMessageEvent, PrivateMessageEvent
+
+from .config import BasePluginConfig, RegexPluginConfig, CommandPluginConfig
+
+T_Config = TypeVar("T_Config", bound=BasePluginConfig)
+T_RegexPluginConfig = TypeVar("T_RegexPluginConfig", bound=RegexPluginConfig)
+T_CommandPluginConfig = TypeVar("T_CommandPluginConfig", bound=CommandPluginConfig)
+
+
+class BasePlugin(
+ Plugin[Union[PrivateMessageEvent, GroupMessageEvent], T_State, T_Config],
+ ABC,
+ Generic[T_State, T_Config],
+):
+ Config: Type[T_Config] = BasePluginConfig
+
+ def format_str(self, format_str: str, message_str: str = "") -> str:
+ return format_str.format(
+ message=message_str,
+ user_name=self.event.sender.nickname,
+ user_id=self.event.sender.user_id,
+ )
+
+ async def rule(self) -> bool:
+ if self.event.adapter.name != "cqhttp":
+ return False
+ if self.event.type != "message_sent":
+ return False
+ if self.config.handle_all_message:
+ return self.str_match(self.event.message.get_plain_text())
+ elif self.config.handle_friend_message:
+ if self.event.message_type == "private":
+ return self.str_match(self.event.message.get_plain_text())
+ elif self.config.handle_group_message:
+ if self.event.message_type == "group":
+ if (
+ self.config.accept_group is None
+ or self.event.group_id in self.config.accept_group
+ ):
+ return self.str_match(self.event.message.get_plain_text())
+ return False
+
+ @abstractmethod
+ def str_match(self, msg_str: str) -> bool:
+ raise NotImplemented
+
+
+class RegexPluginBase(BasePlugin[T_State, T_RegexPluginConfig], ABC):
+ msg_match: re.Match
+ re_pattern: re.Pattern
+ Config: Type[T_RegexPluginConfig] = RegexPluginConfig
+
+ def str_match(self, msg_str: str) -> bool:
+ msg_str = msg_str.strip()
+ self.msg_match = self.re_pattern.fullmatch(msg_str)
+ return bool(self.msg_match)
+
+
+class CommandPluginBase(RegexPluginBase[T_State, T_CommandPluginConfig], ABC):
+ command_match: re.Match
+ command_re_pattern: re.Pattern
+ Config: Type[T_CommandPluginConfig] = CommandPluginConfig
+
+ def str_match(self, msg_str: str) -> bool:
+ if not hasattr(self, "command_re_pattern"):
+ self.command_re_pattern = re.compile(
+ f'[{"".join(self.config.command_prefix)}]'
+ f'({"|".join(self.config.command)})'
+ r"\s*(?P<command_args>.*)",
+ flags=re.I if self.config.ignore_case else 0,
+ )
+ msg_str = msg_str.strip()
+ self.command_match = self.command_re_pattern.fullmatch(msg_str)
+ if not self.command_match:
+ return False
+ self.msg_match = self.re_pattern.fullmatch(
+ self.command_match.group("command_args")
+ )
+ return bool(self.msg_match)
diff --git a/tests/plugins/iamai_plugin_base/config.py b/tests/plugins/iamai_plugin_base/config.py
new file mode 100644
index 0000000..04924e0
--- /dev/null
+++ b/tests/plugins/iamai_plugin_base/config.py
@@ -0,0 +1,30 @@
+from typing import Set, Optional
+
+from iamai import ConfigModel
+
+
+class BasePluginConfig(ConfigModel):
+ __config_name__ = ""
+ handle_all_message: bool = True
+ """是否处理所有类型的消息,此配置为 True 时会覆盖 handle_friend_message 和 handle_group_message。"""
+ handle_friend_message: bool = True
+ """是否处理好友消息。"""
+ handle_group_message: bool = True
+ """是否处理群消息。"""
+ accept_group: Optional[Set[int]] = None
+ """处理消息的群号,仅当 handle_group_message 为 True 时生效,留空表示处理所有群。"""
+ message_str: str = "{user_name}: {message}"
+ """最终发送消息的格式。"""
+
+
+class RegexPluginConfig(BasePluginConfig):
+ pass
+
+
+class CommandPluginConfig(RegexPluginConfig):
+ command_prefix: Set[str] = {".", "。","!",":"}
+ """命令前缀。"""
+ command: Set[str] = {}
+ """命令文本。"""
+ ignore_case: bool = True
+ """忽略大小写。"""
diff --git a/tests/plugins/iamai_plugin_reply/__init__.py b/tests/plugins/iamai_plugin_reply/__init__.py
new file mode 100644
index 0000000..6835ca8
--- /dev/null
+++ b/tests/plugins/iamai_plugin_reply/__init__.py
@@ -0,0 +1,43 @@
+import re
+import json
+
+from plugins.iamai_plugin_base import BasePlugin
+
+from .config import Config
+
+
+class Reply(BasePlugin[None, Config]):
+ priority: int = 1
+ Config = Config
+
+ def __post_init__(self):
+ with open(self.config.data_file, "r",encoding="utf-8") as fp:
+ if self.config.data_type == "json":
+ json_data = json.load(fp)
+ else:
+ raise ValueError(f"data_type must be json, not {self.config.data_type}")
+ self.rule_to_message = {
+ item["rule"]: item["message"]
+ for item in json_data
+ if isinstance(item, dict)
+ and "rule" in item.keys()
+ and "message" in item.keys()
+ }
+
+ async def handle(self) -> None:
+ msg = self.rule_to_message[self.msg_match.re.pattern]
+ if isinstance(msg, str):
+ await self.event.reply(self.format_str(msg, self.msg_match.string))
+ else:
+ await self.event.reply(msg)
+
+ def str_match(self, msg_str: str) -> bool:
+ msg_str = msg_str.strip()
+ for rule in self.rule_to_message.keys():
+ msg_match = re.fullmatch(
+ rule, msg_str, flags=re.I if self.config.ignore_case else 0
+ )
+ if msg_match:
+ self.msg_match = msg_match
+ return bool(self.msg_match)
+ return False
diff --git a/tests/plugins/iamai_plugin_reply/config.py b/tests/plugins/iamai_plugin_reply/config.py
new file mode 100644
index 0000000..e024fb6
--- /dev/null
+++ b/tests/plugins/iamai_plugin_reply/config.py
@@ -0,0 +1,11 @@
+from plugins.iamai_plugin_base import CommandPluginConfig
+
+
+class Config(CommandPluginConfig):
+ __config_name__ = "plugin_reply"
+ data_type: str = "json"
+ """数据类型,目前只支持 json。"""
+ data_file: str = "data/reply_data.json"
+ """数据文件位置。"""
+ ignore_case: bool = True
+ """是否忽略大小写,默认为 True。"""