aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author简律纯 <i@jyunko.cn>2024-03-11 09:40:55 +0800
committer简律纯 <i@jyunko.cn>2024-03-11 09:40:55 +0800
commit93581961abaf7edd2dc89170fb73a97a65857628 (patch)
tree2dcdc9e47bdceb86ad2df23e87137e38fcd015a1
parent67cf02ba9bf39116126ef8360cedff5410a20694 (diff)
parent5e07496ab7f428379f2ecb3505894241b9073b9e (diff)
downloadinfini-93581961abaf7edd2dc89170fb73a97a65857628.tar.gz
infini-93581961abaf7edd2dc89170fb73a97a65857628.zip
Merge branches 'master' and 'master' of https://github.com/HydroRoll-Team/infini
-rw-r--r--CHANGELOG.md18
-rw-r--r--README.md2
-rw-r--r--docs/source/quick-start.md55
-rw-r--r--pyproject.toml4
-rw-r--r--src/infini/core.py35
-rw-r--r--src/infini/exceptions.py2
-rw-r--r--src/infini/input.py3
-rw-r--r--src/infini/loader.py5
-rw-r--r--src/infini/output.py5
-rw-r--r--tests/test_core.py11
-rw-r--r--tests/test_handlers.py9
-rw-r--r--tests/test_workflow.py47
12 files changed, 162 insertions, 34 deletions
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
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)来进行下一步的学习。
diff --git a/pyproject.toml b/pyproject.toml
index cf53ff0c..1aaa83c8 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" },
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/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):
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/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():
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"
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