更改项目名为NebulaShell

This commit is contained in:
Falck
2026-05-02 08:30:31 +08:00
parent d16e28ab17
commit 2c2ec60a2b
233 changed files with 298 additions and 276 deletions

View File

@@ -0,0 +1,83 @@
# json-codec JSON 编解码器
提供插件间 JSON 数据的编码、解码和验证功能。
## 功能
- **JSON 编码**: Python 对象 → JSON 字符串
- **JSON 解码**: JSON 字符串 → Python 对象
- **Schema 验证**: 验证 JSON 数据结构
- **自定义类型**: 支持注册自定义类型编解码器
## 基本使用
```python
codec = plugin_mgr.get("json-codec")
# 编码
data = {"name": "test", "count": 42}
json_str = codec.encode(data)
# '{"name": "test", "count": 42}'
# 编码(格式化)
json_pretty = codec.encode(data, pretty=True)
# '{\n "name": "test",\n "count": 42\n}'
# 解码
parsed = codec.decode(json_str)
# {"name": "test", "count": 42}
```
## HTTP 响应处理
```python
# 在 http-api 插件中使用
router.get("/api/users", lambda req: Response(
status=200,
headers={"Content-Type": "application/json"},
body=codec.encode({"users": [...]})
))
```
## Schema 验证
```python
# 注册 schema
codec.register_schema("user", {
"type": "object",
"required": ["name", "email"],
"properties": {
"name": {"type": "string"},
"email": {"type": "string"},
"age": {"type": "number"}
}
})
# 验证数据
user_data = {"name": "test", "email": "test@example.com"}
is_valid = codec.validate(user_data, "user")
```
## 自定义类型
```python
from datetime import datetime
# 注册自定义编码器
codec.serializer.register_encoder(datetime, lambda dt: dt.isoformat())
# 使用
data = {"created_at": datetime.now()}
json_str = codec.encode(data)
```
## 错误处理
```python
from oss.plugin.types import JsonCodecError
try:
result = codec.decode("invalid json")
except JsonCodecError as e:
print(f"解码失败: {e}")
```

View File

@@ -0,0 +1,8 @@
{
"signature": "IQ8WAvKno6pRp71kIaxXPb7DzTajPeNOQ0FLZMVovufeyTRMbdSJ8z2zQPBPv9O2a1S9bucyZyhg54fNB2DdLfEnrAbmpepZ3CLrj3cn4KaLNGJjxGHYXWIsFXFvLaYIod/ZuFMYPlzDdwnHJwzHZnkGAmCLrJSR+XvuOqYu/xSZekD/nbMI0fj9VKjaH/S/vopEhq7IFioahVkiSokdYx5qkXYruOVAq3wCnk6O0uCNMfHiIaRhn5pEoQ+VOXcuKX5eOBEph8oXqb+ew1MB917Z1CpaLFuZTyp2Dy8OOmpXjBxfd5VYazH4ZvE9Q7VODHkRDVF2ApkPxTE1k490YvmNOHRamjcf1/mKyu7Myaemtz9oxvZFFiOMOaXBXGfe1wlnsbO832lURTpPu9WXQ6aoDEVp3TNuR/G/xYOXHcWhG1M4tIWW+1ZFcozkVw9cMYvwrVI9JEa89sueXQhJG9foW4nj0DJqmtXaXvcVHnpbFkIxcKFZ0rOMelJ7404XuDb07/sjliJuqCG9Gssmv7/DqNgIrcWUPg24U4UPWW2vWJaJq7HOrGrxFoOxpCT/G4A0WcAWVJrM5NojnfvBNswybSB2IIbspmPRDVtoHQ5a3YJqSLZdgugHh+MbGKlyDvPkQTkPLLE8nrP2F0LwWCq0cYeodE+zU0rZ6CHgAsc=",
"signer": "NebulaShell",
"algorithm": "RSA-SHA256",
"timestamp": 1775964952.836965,
"plugin_hash": "a7f7a20614a2e159e393a95c99b15a0a028724694bda3d089787cb41eceba7c4",
"author": "NebulaShell"
}

View File

@@ -0,0 +1,162 @@
"""JSON 编解码器 - 插件间 JSON 数据处理"""
import json
from typing import Any, Callable, Optional
from datetime import datetime
from oss.logger.logger import Log
from oss.plugin.types import Plugin, register_plugin_type
class JsonCodecError(Exception):
"""JSON 编解码错误"""
pass
class JsonSerializer:
"""JSON 序列化器"""
def __init__(self):
self._custom_encoders: dict[type, Callable] = {}
def register_encoder(self, type_class: type, encoder: Callable):
"""注册自定义类型编码器"""
self._custom_encoders[type_class] = encoder
def encode(self, data: Any, pretty: bool = False) -> str:
"""编码为 JSON 字符串"""
def default_handler(obj):
if isinstance(obj, datetime):
return obj.isoformat()
for type_class, encoder in self._custom_encoders.items():
if isinstance(obj, type_class):
return encoder(obj)
raise TypeError(f"无法序列化类型: {type(obj).__name__}")
if pretty:
return json.dumps(data, ensure_ascii=False, indent=2, default=default_handler)
return json.dumps(data, ensure_ascii=False, default=default_handler)
def encode_to_bytes(self, data: Any) -> bytes:
"""编码为字节"""
return self.encode(data).encode("utf-8")
class JsonDeserializer:
"""JSON 反序列化器"""
def __init__(self):
self._custom_decoders: dict[str, Callable] = {}
def register_decoder(self, type_name: str, decoder: Callable):
"""注册自定义类型解码器"""
self._custom_decoders[type_name] = decoder
def decode(self, text: str) -> Any:
"""解码 JSON 字符串"""
try:
return json.loads(text)
except json.JSONDecodeError as e:
raise JsonCodecError(f"JSON 解码失败: {e}")
def decode_bytes(self, data: bytes) -> Any:
"""解码字节"""
return self.decode(data.decode("utf-8"))
def decode_file(self, path: str) -> Any:
"""解码 JSON 文件"""
with open(path, "r", encoding="utf-8") as f:
return self.decode(f.read())
class JsonValidator:
"""JSON 验证器"""
def __init__(self):
self._schemas: dict[str, dict] = {}
def register_schema(self, name: str, schema: dict):
"""注册 schema"""
self._schemas[name] = schema
def validate(self, data: Any, schema_name: str) -> bool:
"""验证数据是否符合 schema"""
if schema_name not in self._schemas:
raise JsonCodecError(f"未知的 schema: {schema_name}")
return self._check_schema(data, self._schemas[schema_name])
def _check_schema(self, data: Any, schema: dict) -> bool:
"""检查 schema 匹配"""
schema_type = schema.get("type")
if schema_type == "object":
if not isinstance(data, dict):
return False
required = schema.get("required", [])
for field in required:
if field not in data:
return False
properties = schema.get("properties", {})
for key, value in data.items():
if key in properties:
if not self._check_schema(value, properties[key]):
return False
return True
elif schema_type == "array":
if not isinstance(data, list):
return False
items_schema = schema.get("items", {})
return all(self._check_schema(item, items_schema) for item in data)
elif schema_type == "string":
return isinstance(data, str)
elif schema_type == "number":
return isinstance(data, (int, float))
elif schema_type == "boolean":
return isinstance(data, bool)
return True
class JsonCodecPlugin(Plugin):
"""JSON 编解码器插件"""
def __init__(self):
self.serializer = JsonSerializer()
self.deserializer = JsonDeserializer()
self.validator = JsonValidator()
def init(self, deps: dict = None):
"""初始化"""
pass
def start(self):
"""启动"""
Log.info("json-codec", "JSON 编解码器已启动")
def stop(self):
"""停止"""
pass
def encode(self, data: Any, pretty: bool = False) -> str:
"""编码 JSON"""
return self.serializer.encode(data, pretty)
def decode(self, text: str) -> Any:
"""解码 JSON"""
return self.deserializer.decode(text)
def validate(self, data: Any, schema_name: str) -> bool:
"""验证 JSON schema"""
return self.validator.validate(data, schema_name)
def register_schema(self, name: str, schema: dict):
"""注册 schema"""
self.validator.register_schema(name, schema)
# 注册类型
register_plugin_type("JsonSerializer", JsonSerializer)
register_plugin_type("JsonDeserializer", JsonDeserializer)
register_plugin_type("JsonValidator", JsonValidator)
register_plugin_type("JsonCodecError", JsonCodecError)
def New():
return JsonCodecPlugin()

View File

@@ -0,0 +1,15 @@
{
"metadata": {
"name": "json-codec",
"version": "1.0.0",
"author": "NebulaShell",
"description": "JSON 编解码器 - 插件间 JSON 数据处理和验证",
"type": "utility"
},
"config": {
"enabled": true,
"args": {}
},
"dependencies": [],
"permissions": []
}