subs-io适配引入saa后的新数据库结构 (#219的subs-io部分) (#224)

* 🚚 将nbesf_model统一放到目录中

*  添加v2版本的nbesf

*  使subs_import支持导入多个版本的nbesf文件

*  使用saa的AllSupportedPlatformTarget

* 🚧 use deserialize

---------

Co-authored-by: felinae98 <731499577@qq.com>
This commit is contained in:
AzideCupric
2023-05-08 02:27:05 +08:00
committed by felinae98
parent da8e988ee9
commit 39c045c63f
19 changed files with 678 additions and 180 deletions
+57
View File
@@ -0,0 +1,57 @@
{
"version": 2,
"groups": [
{
"user_target": {
"platform_type": "QQ Group",
"group_id": 1232
},
"subs": [
{
"categories": [],
"tags": [],
"target": {
"target_name": "weibo_name",
"target": "weibo_id",
"platform_name": "weibo",
"default_schedule_weight": 10
}
}
]
},
{
"user_target": {
"platform_type": "QQ Group",
"group_id": 2342
},
"subs": [
{
"categories": [],
"tags": [
"kaltsit",
"amiya"
],
"target": {
"target_name": "weibo_name",
"target": "weibo_id",
"platform_name": "weibo",
"default_schedule_weight": 10
}
},
{
"categories": [
1,
2
],
"tags": [],
"target": {
"target_name": "bilibili_name",
"target": "bilibili_id",
"platform_name": "bilibili",
"default_schedule_weight": 10
}
}
]
}
]
}
+35
View File
@@ -0,0 +1,35 @@
version: 2
groups:
- subs:
- categories: []
tags: []
target:
default_schedule_weight: 10
platform_name: weibo
target: weibo_id
target_name: weibo_name
user_target:
platform_type: QQ Group
group_id: 123552
- subs:
- categories: []
tags:
- kaltsit
- amiya
target:
default_schedule_weight: 10
platform_name: weibo
target: weibo_id
target_name: weibo_name
- categories:
- 1
- 2
tags: []
target:
default_schedule_weight: 10
platform_name: bilibili
target: bilibili_id
target_name: bilibili_name
user_target:
platform_type: QQ Group
group_id: 234662
@@ -0,0 +1,91 @@
{
"version": 1,
"groups": [
{
"user_target": {
"platform_type": "QQ Group",
"group_id": 123
},
"subs": [
{
"categories": [],
"tags": [],
"target": {
"target_name": "weibo_name",
"target": "weibo_id",
"platform_name": "weibo",
"default_schedule_weight": 10
}
}
]
},
{
"user_target": {
"platform_type": "QQ Group",
"group_id": 234
},
"subs": [
{
"tags": [
"kaltsit",
"amiya"
],
"target": {
"target_name": "weibo_name",
"target": "weibo_id",
"platform_name": "weibo",
"default_schedule_weight": 10
}
},
{
"categories": [
1,
2
],
"tags": [],
"target": [
{
"target_name": "bilibili_name",
"target": "bilibili_id",
"platform_name": "bilibili",
"default_schedule_weight": 10
}
]
}
]
},
{
"user_target": {
"platform_type": "QQ Group",
"group_id": 123
},
"subs": {
"categories": [],
"tags": [],
"target": {
"target_name": "weibo_name2",
"target": "weibo_id2",
"platform_name": "weibo",
"default_schedule_weight": 10
}
}
},
{
"user_target": {
"platform_type": "QQ Group",
"group_id": 123
},
"subs": [
{
"categories": [],
"tags": [],
"target": {
"target_name": "weibo_name2",
"platform_name": "weibo",
"default_schedule_weight": 10
}
}
]
}
]
}
@@ -0,0 +1,90 @@
{
"version": 2,
"groups": [
{
"user_target": {
"platform_type": "QQ Group",
"group_id": 1232
},
"subs": [
{
"categories": [],
"tags": [],
"target": {
"target_name": "weibo_name",
"target": "weibo_id",
"platform_name": "weibo",
"default_schedule_weight": 10
}
}
]
},
{
"user_target": {
"platform_type": "QQ Group",
"group_id": 2342
},
"subs": [
{
"categories": [],
"tags": [
"kaltsit",
"amiya"
],
"target": {
"target_name": "weibo_name",
"target": "weibo_id",
"platform_name": "weibo",
"default_schedule_weight": 10
}
},
{
"categories": [
1,
2
],
"tags": [],
"target": {
"target_name": "bilibili_name",
"target": "bilibili_id",
"platform_name": "bilibili",
"default_schedule_weight": 10
}
}
]
},
{
"user_target": {
"platform_type": "QQ Group",
"group_id": 1232
},
"subs": [
{
"categories": [],
"tags": [],
"target": {
"target_name": "weibo_name",
"target": "weibo_id",
"platform_name": "weibo",
"default_schedule_weight": 10
}
},
{
"categories": [
2,
6
],
"tags": [
"poca"
],
"target": {
"target_name": "weibo_name2",
"target": "weibo_id2",
"platform_name": "weibo",
"default_schedule_weight": 10
}
}
]
}
]
}
+46 -12
View File
@@ -35,13 +35,14 @@ def test_cli_help(app: App):
async def test_subs_export(app: App, tmp_path: Path):
from nonebot_plugin_saa import TargetQQGroup
from nonebot_bison.config.db_config import config
from nonebot_bison.script.cli import cli, run_sync
from nonebot_bison.types import Target as TTarget
await config.add_subscribe(
user=123,
user_type="group",
TargetQQGroup(group_id=123),
target=TTarget("weibo_id"),
target_name="weibo_name",
platform_name="weibo",
@@ -49,8 +50,7 @@ async def test_subs_export(app: App, tmp_path: Path):
tags=[],
)
await config.add_subscribe(
user=234,
user_type="group",
TargetQQGroup(group_id=234),
target=TTarget("weibo_id"),
target_name="weibo_name",
platform_name="weibo",
@@ -58,8 +58,7 @@ async def test_subs_export(app: App, tmp_path: Path):
tags=["kaltsit", "amiya"],
)
await config.add_subscribe(
user=234,
user_type="group",
TargetQQGroup(group_id=234),
target=TTarget("bilibili_id"),
target_name="bilibili_name",
platform_name="bilibili",
@@ -80,7 +79,8 @@ async def test_subs_export(app: App, tmp_path: Path):
assert result.exit_code == 0
file_path = Path.cwd() / "bison_subscribes_export_1.json"
assert file_path.exists()
assert file_path.stat().st_size
assert '"version": 2' in file_path.read_text()
assert '"group_id": 123' in file_path.read_text()
# 是否导出到指定已存在文件夹
data_dir = tmp_path / "data"
@@ -89,7 +89,8 @@ async def test_subs_export(app: App, tmp_path: Path):
assert result.exit_code == 0
file_path2 = data_dir / "bison_subscribes_export_1.json"
assert file_path2.exists()
assert file_path2.stat().st_size
assert '"version": 2' in file_path2.read_text()
assert '"group_id": 123' in file_path2.read_text()
# 是否拒绝导出到不存在的文件夹
result = await run_sync(runner.invoke)(
@@ -104,7 +105,9 @@ async def test_subs_export(app: App, tmp_path: Path):
assert result.exit_code == 0
file_path3 = tmp_path / "bison_subscribes_export_1.yaml"
assert file_path3.exists()
assert file_path3.stat().st_size
assert "version: 2" in file_path3.read_text()
assert "group_id: 123" in file_path3.read_text()
assert "platform_type: QQ Group" in file_path3.read_text()
# 是否允许以未支持的格式导出
result = await run_sync(runner.invoke)(
@@ -113,14 +116,14 @@ async def test_subs_export(app: App, tmp_path: Path):
assert result.exit_code == 2
async def test_subs_import(app: App, tmp_path):
async def test_subs_import_v1(app: App, tmp_path):
from nonebot_bison.config.db_config import config
from nonebot_bison.script.cli import cli, run_sync
assert len(await config.list_subs_with_all_info()) == 0
mock_file: Path = tmp_path / "1.json"
mock_file.write_text(get_file("subs_export.json"))
mock_file.write_text(get_file("v1/subs_export.json"))
runner = CliRunner()
@@ -135,7 +138,38 @@ async def test_subs_import(app: App, tmp_path):
assert len(await config.list_subs_with_all_info()) == 3
mock_file: Path = tmp_path / "2.yaml"
mock_file.write_text(get_file("subs_export.yaml"))
mock_file.write_text(get_file("v1/subs_export.yaml"))
result = await run_sync(runner.invoke)(
cli, ["import", "-p", str(mock_file), "--format=yml"]
)
assert result.exit_code == 0
assert len(await config.list_subs_with_all_info()) == 6
async def test_sub_import_v2(app: App, tmp_path):
from nonebot_bison.config.db_config import config
from nonebot_bison.script.cli import cli, run_sync
assert len(await config.list_subs_with_all_info()) == 0
mock_file: Path = tmp_path / "1.json"
mock_file.write_text(get_file("v2/subs_export.json"))
runner = CliRunner()
result = await run_sync(runner.invoke)(cli, ["import"])
assert result.exit_code == 2
result = await run_sync(runner.invoke)(cli, ["import", "-p"])
assert result.exit_code == 2
result = await run_sync(runner.invoke)(cli, ["import", "-p", str(mock_file)])
assert result.exit_code == 0
assert len(await config.list_subs_with_all_info()) == 3
mock_file: Path = tmp_path / "2.yaml"
mock_file.write_text(get_file("v2/subs_export.yaml"))
result = await run_sync(runner.invoke)(
cli, ["import", "-p", str(mock_file), "--format=yml"]
+67 -21
View File
@@ -1,22 +1,21 @@
from pathlib import Path
import pytest
from nonebug.app import App
from .utils import get_file, get_json
from .utils import get_json
async def test_subs_export(app: App, init_scheduler):
import time
from nonebot_plugin_saa import TargetQQGroup
from nonebot_bison.config.db_config import config
from nonebot_bison.config.db_model import User
from nonebot_bison.config.subs_io import subscribes_export
from nonebot_bison.types import Target as TTarget
await config.add_subscribe(
user=123,
user_type="group",
TargetQQGroup(group_id=1232),
target=TTarget("weibo_id"),
target_name="weibo_name",
platform_name="weibo",
@@ -24,8 +23,7 @@ async def test_subs_export(app: App, init_scheduler):
tags=[],
)
await config.add_subscribe(
user=234,
user_type="group",
TargetQQGroup(group_id=2342),
target=TTarget("weibo_id"),
target_name="weibo_name",
platform_name="weibo",
@@ -33,8 +31,7 @@ async def test_subs_export(app: App, init_scheduler):
tags=["kaltsit", "amiya"],
)
await config.add_subscribe(
user=234,
user_type="group",
TargetQQGroup(group_id=2342),
target=TTarget("bilibili_id"),
target_name="bilibili_name",
platform_name="bilibili",
@@ -46,46 +43,95 @@ async def test_subs_export(app: App, init_scheduler):
assert len(data) == 3
nbesf_data = await subscribes_export(lambda x: x)
assert nbesf_data.dict() == get_json("subs_export.json")
print(nbesf_data.dict())
assert nbesf_data.dict() == get_json("v2/subs_export.json")
nbesf_data_user_234 = await subscribes_export(
lambda stmt: stmt.where(User.uid == 234, User.type == "group")
lambda stmt: stmt.where(
User.user_target == {"platform_type": "QQ Group", "group_id": 2342}
)
)
assert len(nbesf_data_user_234.groups) == 1
assert len(nbesf_data_user_234.groups[0].subs) == 2
assert nbesf_data_user_234.groups[0].user.dict() == {"uid": 234, "type": "group"}
assert nbesf_data_user_234.groups[0].user_target == {
"group_id": 2342,
"platform_type": "QQ Group",
}
async def test_subs_import(app: App, init_scheduler):
from nonebot_bison.config.db_config import config
from nonebot_bison.config.subs_io import nbesf_parser, subscribes_import
from nonebot_bison.config.subs_io import subscribes_import
from nonebot_bison.config.subs_io.nbesf_model import v1, v2
nbesf_data = nbesf_parser(get_json("subs_export.json"))
# v1
nbesf_data_v1 = v1.nbesf_parser(get_json("v1/subs_export.json"))
await subscribes_import(nbesf_data)
await subscribes_import(nbesf_data_v1)
data = await config.list_subs_with_all_info()
assert len(data) == 3
# v2
nbesf_data_v2 = v2.nbesf_parser(get_json("v2/subs_export.json"))
await subscribes_import(nbesf_data_v2)
data = await config.list_subs_with_all_info()
assert len(data) == 6
async def test_subs_import_dup_err(app: App, init_scheduler):
from nonebot_bison.config.db_config import config
from nonebot_bison.config.subs_io import nbesf_parser, subscribes_import
from nonebot_bison.config.subs_io import subscribes_import
from nonebot_bison.config.subs_io.nbesf_model import v1, v2
nbesf_data = nbesf_parser(get_json("subs_export_has_subdup_err.json"))
# v1
nbesf_data_v1 = v1.nbesf_parser(get_json("v1/subs_export_has_subdup_err.json"))
await subscribes_import(nbesf_data)
await subscribes_import(nbesf_data_v1)
data = await config.list_subs_with_all_info()
assert len(data) == 4
# v2
nbesf_data_v2 = v2.nbesf_parser(get_json("v2/subs_export_has_subdup_err.json"))
await subscribes_import(nbesf_data_v2)
data = await config.list_subs_with_all_info()
assert len(data) == 8
async def test_subs_import_version_disorder(app: App, init_scheduler):
from nonebot_bison.config.db_config import config
from nonebot_bison.config.subs_io import subscribes_import
from nonebot_bison.config.subs_io.nbesf_model import v1, v2
from nonebot_bison.config.subs_io.utils import NBESFParseErr
# use v2 parse v1
with pytest.raises(NBESFParseErr):
nbesf_data_v1 = v1.nbesf_parser(get_json("v2/subs_export_has_subdup_err.json"))
# use v1 parse v2
with pytest.raises(NBESFParseErr):
nbesf_data_v2 = v2.nbesf_parser(get_json("v1/subs_export_has_subdup_err.json"))
with pytest.raises(AssertionError):
nbesf_data = v2.nbesf_parser(get_json("v2/subs_export_has_subdup_err.json"))
nbesf_data.version = 1
await subscribes_import(nbesf_data)
async def test_subs_import_all_fail(app: App, init_scheduler):
"""只要文件格式有任何一个错误, 都不会进行订阅"""
from nonebot_bison.config.subs_io import nbesf_parser
from nonebot_bison.config.subs_io.nbesf_model import NBESFParseErr
from nonebot_bison.config.subs_io.nbesf_model import v1, v2
from nonebot_bison.config.subs_io.nbesf_model.v1 import NBESFParseErr
with pytest.raises(NBESFParseErr):
nbesf_data = nbesf_parser(get_json("subs_export_all_illegal.json"))
nbesf_data = v1.nbesf_parser(get_json("v1/subs_export_all_illegal.json"))
with pytest.raises(NBESFParseErr):
nbesf_data = v2.nbesf_parser(get_json("v2/subs_export_all_illegal.json"))