From 7461b8822efe61a2c9c3383907d199eb634e34ff Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Mon, 4 Mar 2024 16:21:59 +0800 Subject: docs(quick-start): add ipm tutorial --- README.md | 2 +- docs/source/quick-start.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6de51af7..b17ab2c8 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Infini 2 是一个先进的内容输入输出流标准框架,它的诞生源于对于平台机器人的代码复用问题,以及指令的动态解析问题。Infini 2 的规则包是可热插拔的,它以使用 Infini 框架的规则包为最小热插拔单元,以`输入→预拦截→业务函数→内容生成→内容拦截→输出`为一整套 Infini 输入输出流程式,规则包可以定制化的注册任一流程层次的处理函数。 -Infini 2 同样是**跨平台跨框架**的。你可以在任何支持 Python 的平台运行 Infini,同样的,你在对接平台时,可以选用任何框架来适配 Infini 2,例如[`Nonebot2`](https://github.com/nonebot/nonebot2)、[`Avilla`](https://github.com/GraiaProject/Avilla)和[`iamai`](https://github.com/retrofor/iamai/)等,而这些框架都是跨平台和跨协议的,这意味着 Infini 2 同样是跨平台和跨协议支持的。Infini 可能将在未来版本支持直接对接平台协议。 +Infini 2 同样是**跨平台跨框架**的。你可以在任何支持 Python 的平台运行 Infini,同样的,你在对接平台时,可以选用任何框架来适配 Infini 2,例如[`Nonebot2`](https://nonebot.dev/)、[`OlivOS`](https://doc.olivos.wiki/)和[`iamai`](https://github.com/retrofor/iamai/)等,而这些框架都是跨平台和跨协议的,这意味着 Infini 2 同样是跨平台和跨协议支持的。Infini 可能将在未来版本支持直接对接平台协议。 Infini 2 所有层次的业务函数都是依照参数名进行**依赖注入**的,你可以动态的选择你所需要的注入参数。由于先进的架构特性,Infini 2 可以省去大量的开发时间,节约开发成本。同时由于其轻量的输入输出流程式,它拥有较低的学习成本。 diff --git a/docs/source/quick-start.md b/docs/source/quick-start.md index bb1a5a95..7f08e0f6 100644 --- a/docs/source/quick-start.md +++ b/docs/source/quick-start.md @@ -21,3 +21,58 @@ ### Infini 包管理器 我们强烈推荐使用 Infini 包管理器——**IPM**来构建一个 Python 规则包。 + +你可以通过执行终端指令来安装 IPM: + +```bash +pip install ipdm +``` + +安装完成后,在终端中执行`ipm`确保 IPM 被正确安装。 + +## 创建项目 + +1. 使用 IPM 创建规则包 + + 你可以使用以下指令创建 Infini 规则包: + + ```bash + ipm new yourpackage + ``` + + IPM 将为你初始化一个 Infini 规则包,你应该将`yourpackage`替换为你的包名。 + + 也可以在已有的文件夹内创建: + + ```bash + cd exists_directory + ipm init + ``` + + 这两者是等效的。 + + 你可以前往[IPM 文档](https://ipm.hydroroll.team/)获得更多关于 IPM 使用的信息。 + +2. 手动创建规则包 + + 首先在一个目录中创建`infini.toml`,并写入以下内容: + + ```toml + [infini] + name = "yourpackage" + version = "0.1.0" + description = "规则包描述" + license = "AGPLv3" + + [requirements] + + [dependencies] + ``` + + 然后在同一个目录创建一个`src`文件夹,并在`src`中建立一个入口文件(`__init__.py`或`yourpackage.py`,这两者是等效的)。 + +## 正式开始 + +以上你已经成功建立了 Infini 开发环境,现在你可以开始学习如何构建一个你自己的规则包了。 + +Infini 2 规则包应当遵循规定的规则包标准,你可以前往阅读[通用规则包标准文档](grps/index)来进行下一步的学习。 -- cgit v1.2.3-70-g09d2 From edf6101277450d9b849f329cdfe27ad204c84392 Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Mon, 4 Mar 2024 17:54:47 +0800 Subject: feat(workflow): supports blocked workflow --- src/infini/core.py | 35 +++++++++++++++++++++++++++-------- src/infini/input.py | 3 +-- src/infini/output.py | 5 ++--- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/infini/core.py b/src/infini/core.py index 7c84a15f..0de6034c 100644 --- a/src/infini/core.py +++ b/src/infini/core.py @@ -15,9 +15,7 @@ class Core: interceptor: Interceptor injector: Injector - def input( - self, input: Input - ) -> GeneratorT[Union[str, Output], Any, None]: + def input(self, input: Input) -> GeneratorT[Union[str, Output], Any, None]: for pre_intercepted_stream in self.pre_intercept(input): if isinstance(pre_intercepted_stream, Output): if not isinstance(pre_intercepted_stream, Output): @@ -26,7 +24,15 @@ class Core: ) if pre_intercepted_stream.is_empty(): return - yield self.generate(pre_intercepted_stream) + if pre_intercepted_stream.type == "workflow": + yield pre_intercepted_stream + if pre_intercepted_stream.block: + while pre_intercepted_stream.status != 0: + pass + continue + else: + yield self.generate(pre_intercepted_stream) # TODO 拦截拦截器文本 + if pre_intercepted_stream.block: return else: @@ -39,14 +45,27 @@ class Core: ) if handled_stream.is_empty(): return - outcome = self.generate(handled_stream) + if handled_stream.type == "workflow": + yield handled_stream + if handled_stream.block: + while handled_stream.status != 0: + pass + continue + else: + outcome = self.generate(handled_stream) for stream in self.intercept(handled_stream, outcome): if isinstance(stream, Output): if stream.is_empty(): return - yield self.generate(stream) - if stream.block: - return + if stream.type == "workflow": + yield stream + if stream.block: + while stream.status != 0: + pass + else: + yield self.generate(stream) + if stream.block: + return continue outcome = stream yield outcome diff --git a/src/infini/input.py b/src/infini/input.py index 30683a4b..0bbb3f2f 100644 --- a/src/infini/input.py +++ b/src/infini/input.py @@ -32,10 +32,9 @@ class Input(Generic[T]): type: Literal["text", "workflow"], name: str, *, - status: int = 0, block: bool = False, variables: Dict[str, Any] = {}, ): vars = self.variables.copy() vars.update(variables) - return Output(type, name, status=status, block=block, variables=vars) + return Output(type, name, block=block, variables=vars) diff --git a/src/infini/output.py b/src/infini/output.py index 13f26d47..6520d9b4 100644 --- a/src/infini/output.py +++ b/src/infini/output.py @@ -14,19 +14,18 @@ class Output: type: Union[Literal["null", "text", "workflow"], str], name: str, *, - status: int = 0, block: bool = False, variables: Dict[str, Any] = {}, ) -> None: self.type = type self.name = name - self.status = status + self.status = 1 self.block = block self.variables = variables @classmethod def empty(cls) -> "Output": - return cls("null", "null", status=0, block=True) + return cls("null", "null", block=True) def is_empty(self) -> bool: return self.type == "null" -- cgit v1.2.3-70-g09d2 From 5b778ed5ea34862969653a4fc4e72d1debe09ee1 Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Mon, 4 Mar 2024 17:55:52 +0800 Subject: style(exception): fix annocation --- src/infini/exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/infini/exceptions.py b/src/infini/exceptions.py index 2e2b0197..ac9c3d22 100644 --- a/src/infini/exceptions.py +++ b/src/infini/exceptions.py @@ -11,7 +11,7 @@ class UnknownEvent(InfiniException): class UnknownEventType(InfiniException, TypeError): - """文本事件不存在""" + """事件类型不存在""" class ValueError(InfiniException, ValueError): -- cgit v1.2.3-70-g09d2 From f195a1e7396b7eaa23ef6f14ffebb700cf741c75 Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Mon, 4 Mar 2024 17:56:12 +0800 Subject: test(workflow): add tests for workflow feature --- tests/test_core.py | 11 +++++------ tests/test_handlers.py | 9 +++------ tests/test_workflow.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 12 deletions(-) create mode 100644 tests/test_workflow.py diff --git a/tests/test_core.py b/tests/test_core.py index 5f3f12f1..bcab2d4a 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1,5 +1,5 @@ from infini.core import Core -from infini.generator import TextGenerator +from infini.generator import Generator from infini.handler import Handler from infini.injector import Injector from infini.input import Input @@ -28,12 +28,10 @@ def test_core(): def add(input: Input) -> Output: result = str(sum(list(map(int, input.get_plain_text().lstrip(".add").split())))) - return Output( - "text", "test.add", status=0, block=False, variables={"result": result} - ) + return Output("text", "test.add", block=False, variables={"result": result}) def cmd(_: Input) -> Output: - return Output("text", "test.cmd", status=0, block=False) + return Output("text", "test.cmd", block=False) handler = Handler() handler.handlers = [ @@ -49,12 +47,13 @@ def test_core(): }, ] - generator = TextGenerator() + generator = Generator() generator.events = { "test.cmd": "cmd", "test.add": "{{ result }}", "block.jianlvchun": "检测到违禁词", } + generator.global_variables = {} core = Core() core.handler = handler diff --git a/tests/test_handlers.py b/tests/test_handlers.py index ee96cdab..79810ce0 100644 --- a/tests/test_handlers.py +++ b/tests/test_handlers.py @@ -11,12 +11,11 @@ def test_handler(): return Output( "text", str(sum(list(map(int, input.get_plain_text().lstrip(".add").split())))), - status=0, block=False, ) def cmd(_: Input) -> Output: - return Output("text", "cmd", status=0, block=False) + return Output("text", "cmd", block=False) handler = Handler() handler.handlers = [ @@ -45,12 +44,11 @@ def test_handler_block(): return Output( "text", str(sum(list(map(int, input.get_plain_text().lstrip(".add").split())))), - status=0, block=False, ) def cmd(_: Input) -> Output: - return Output("text", "cmd", status=0, block=True) + return Output("text", "cmd", block=True) handler = Handler() handler.handlers = [ @@ -79,10 +77,9 @@ def test_handler_interator(): yield Output( "text", str(sum(list(map(int, input.get_plain_text().lstrip(".add").split())))), - status=0, block=False, ) - yield Output("text", "ok", status=0, block=False) + yield Output("text", "ok", block=False) handler = Handler() handler.handlers = [ diff --git a/tests/test_workflow.py b/tests/test_workflow.py new file mode 100644 index 00000000..18dab9d5 --- /dev/null +++ b/tests/test_workflow.py @@ -0,0 +1,47 @@ +from infini.core import Core +from infini.generator import Generator +from infini.handler import Handler +from infini.injector import Injector +from infini.input import Input +from infini.interceptor import Interceptor +from infini.output import Output +from infini.router import Startswith + + +def test_workflow(): + def func_workflow(input: Input): + yield input.output("workflow", "test.workflow", block=True) + + input = Input("testmsg") + + handler = Handler() + handler.handlers = [ + { + "priority": 0, + "router": Startswith(""), + "handler": func_workflow, + } + ] + + interceptor = Interceptor() + interceptor.interceptors = [] + + generator = Generator() + generator.events = { + "test.cmd": "cmd", + "test.add": "{{ result }}", + "block.jianlvchun": "检测到违禁词", + } + generator.global_variables = {} + + core = Core() + core.handler = handler + core.interceptor = interceptor + core.pre_interceptor = interceptor + core.generator = generator + core.injector = Injector() + + for output in core.input(input): + assert isinstance(output, Output) + assert output.type == "workflow" + output.status = 0 -- cgit v1.2.3-70-g09d2 From a937d5d3ed0e2bec8e813cd6dfd4c408d902a92b Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Mon, 4 Mar 2024 17:56:54 +0800 Subject: feat(loader): supports hot module reload --- src/infini/loader.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/infini/loader.py b/src/infini/loader.py index 07ebe0a8..f02dd910 100644 --- a/src/infini/loader.py +++ b/src/infini/loader.py @@ -82,10 +82,7 @@ class InfiniLoader(importlib.abc.Loader): def _install(): - if not sys.meta_path: - raise OSError("Var 'sys.meta_path' is empty, since Python is stop.") - if not isinstance(sys.meta_path[0], InfiniMetaFinder): - sys.meta_path.insert(0, InfiniMetaFinder()) + sys.meta_path.insert(0, InfiniMetaFinder()) def _uninstall(): -- cgit v1.2.3-70-g09d2 From ee6eea0831f14c85046f906d9ab3fbb5f7e81320 Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Mon, 4 Mar 2024 17:57:50 +0800 Subject: chore(version): bump version to v2.1.1 --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index df59c56c..ab432558 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "infini" -version = "2.1.0" -description = "Infini 轻量输入输出流框架" +version = "2.1.1" +description = "Infini 内容输入输出流框架" authors = [ { name = "苏向夜", email = "fu050409@163.com" }, { name = "简律纯", email = "leader@hydroroll.team" }, -- cgit v1.2.3-70-g09d2 From 5e07496ab7f428379f2ecb3505894241b9073b9e Mon Sep 17 00:00:00 2001 From: fu050409 Date: Mon, 4 Mar 2024 09:58:31 +0000 Subject: docs: update CHANGELOG.md for v2.1.1 [skip ci] --- CHANGELOG.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec4a847b..8bbdbdca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v2.1.1] - 2024-03-04 +### New Features +- [`4f3c342`](https://github.com/HydroRoll-Team/infini/commit/4f3c34290bcd172a35a86b172e27ca52910aa4b6) - **quick-start**: fix tip block *(commit by [@fu050409](https://github.com/fu050409))* +- [`edf6101`](https://github.com/HydroRoll-Team/infini/commit/edf6101277450d9b849f329cdfe27ad204c84392) - **workflow**: supports blocked workflow *(commit by [@fu050409](https://github.com/fu050409))* +- [`a937d5d`](https://github.com/HydroRoll-Team/infini/commit/a937d5d3ed0e2bec8e813cd6dfd4c408d902a92b) - **loader**: supports hot module reload *(commit by [@fu050409](https://github.com/fu050409))* + +### Tests +- [`f195a1e`](https://github.com/HydroRoll-Team/infini/commit/f195a1e7396b7eaa23ef6f14ffebb700cf741c75) - **workflow**: add tests for workflow feature *(commit by [@fu050409](https://github.com/fu050409))* + +### Chores +- [`4bf8089`](https://github.com/HydroRoll-Team/infini/commit/4bf8089999650b6e08796d4b7e6288a67b9cb2cd) - **docs**: update docs conf.py for new domain *(commit by [@HsiangNianian](https://github.com/HsiangNianian))* +- [`9425a63`](https://github.com/HydroRoll-Team/infini/commit/9425a632d234229ee87178c69f572384e9713fae) - **docs**: delete chapter grps *(commit by [@HsiangNianian](https://github.com/HsiangNianian))* +- [`ee6eea0`](https://github.com/HydroRoll-Team/infini/commit/ee6eea0831f14c85046f906d9ab3fbb5f7e81320) - **version**: bump version to v2.1.1 *(commit by [@fu050409](https://github.com/fu050409))* + + ## [v2.1.0] - 2024-03-04 ### New Features - [`0f32d6f`](https://github.com/HydroRoll-Team/infini/commit/0f32d6f3520e03a48f9143f2a4f7e48be7742e9b) - **injector**: supports backend function injector *(commit by [@fu050409](https://github.com/fu050409))* @@ -107,4 +122,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [v2.0.5]: https://github.com/HydroRoll-Team/infini/compare/v2.0.4...v2.0.5 [v2.0.6]: https://github.com/HydroRoll-Team/infini/compare/v2.0.5...v2.0.6 [v2.0.7]: https://github.com/HydroRoll-Team/infini/compare/v2.0.6...v2.0.7 -[v2.1.0]: https://github.com/HydroRoll-Team/infini/compare/v2.0.7...v2.1.0 \ No newline at end of file +[v2.1.0]: https://github.com/HydroRoll-Team/infini/compare/v2.0.7...v2.1.0 +[v2.1.1]: https://github.com/HydroRoll-Team/infini/compare/v2.1.0...v2.1.1 \ No newline at end of file -- cgit v1.2.3-70-g09d2