This commit is contained in:
felinae98 2022-02-16 21:42:49 +08:00
parent a0b98f5c9c
commit 78276e51ee
No known key found for this signature in database
GPG Key ID: 00C8B010587FF610
12 changed files with 317 additions and 113 deletions

View File

@ -34,19 +34,50 @@ sidebar: auto
#### 这个平台是否有账号的概念 #### 这个平台是否有账号的概念
- `nonebot_bison.platform.platform.TargetMixin` 有账号的概念 - 有账号的概念
例如Bilibili 用户,微博用户 例如B 用户动态,微博用户动态,网易云电台更新
- `nonebot_bison.platform.platform.NoTargetMixin` 没有账号的概念 - 没有账号的概念
例如:游戏公告,教务处公告 例如:游戏公告,教务处公告
现在你已经选择了两个类,现在你需要在`src/plugins/nonebot_bison/platform`下新建一个 py 文件, 现在你需要在`src/plugins/nonebot_bison/platform`下新建一个 py 文件,
在里面新建一个类,继承你刚刚选择的两个类,重载一些关键的函数,然后……就完成了,不需要修改别的东西了。 在里面新建一个类,继承推送类型的基类,重载一些关键的函数,然后……就完成了,不需要修改别的东西了。
例如要适配微博,微博有账号,并且我希望 bot 搬运新的消息,所以微博的类应该这样定义: 任何一种订阅类型需要实现的方法/字段如下:
- `schedule_type`, `schedule_kw` 调度的参数,本质是使用 apscheduler 的[trigger 参数](https://apscheduler.readthedocs.io/en/3.x/userguide.html?highlight=trigger#choosing-the-right-scheduler-job-store-s-executor-s-and-trigger-s)`schedule_type`可以是`date`,`interval``cron`
`schedule_kw`是对应的参数,一个常见的配置是`schedule_type=interval`, `schedule_kw={'seconds':30}`
- `is_common` 是否常用,如果被标记为常用,那么和机器人交互式对话添加订阅时,会直接出现在选择列表中,否则
需要输入`全部`才会出现。
- `enabled` 是否启用
- `name` 平台的正式名称,例如`微博`
- `has_target` 平台是否有“帐号”
- `category` 平台的发布内容分类,例如 B 站包括专栏,视频,图文动态,普通动态等,如果不包含分类功能则设为`{}`
- `enable_tag` 平台发布内容是否带 Tag例如微博
- `platform_name` 唯一的,英文的识别标识,比如`weibo`
- `async get_target_name(Target) -> Optional[str]` 通常用于获取帐号的名称,如果平台没有帐号概念,可以直接返回平台的`name`
- `async parse(RawPost) -> Post`将获取到的 RawPost 处理成 Post
- `get_tags(RawPost) -> Optional[Collection[Tag]]` (可选) 从 RawPost 中提取 Tag
- `get_category(RawPos) -> Optional[Category]` (可选)从 RawPost 中提取 Category
例如要适配微博,我希望 bot 搬运新的消息,所以微博的类应该这样定义:
```python ```python
class Weibo(NewMessage, TargetMixin): class Weibo(NewMessage):
...
categories = {
1: "转发",
2: "视频",
3: "图文",
4: "文字",
}
enable_tag = True
platform_name = "weibo"
name = "新浪微博"
enabled = True
is_common = True
schedule_type = "interval"
schedule_kw = {"seconds": 3}
has_target = True
``` ```
当然我们非常希望你对自己适配的平台写一些单元测试,你可以模仿`tests/platforms/test_*.py`中的内容写 当然我们非常希望你对自己适配的平台写一些单元测试,你可以模仿`tests/platforms/test_*.py`中的内容写

76
poetry.lock generated
View File

@ -325,7 +325,7 @@ tests = ["dill", "coverage", "coveralls", "mock", "nose"]
[[package]] [[package]]
name = "fastapi" name = "fastapi"
version = "0.70.1" version = "0.73.0"
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
category = "main" category = "main"
optional = false optional = false
@ -333,12 +333,12 @@ python-versions = ">=3.6.1"
[package.dependencies] [package.dependencies]
pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0" pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0"
starlette = "0.16.0" starlette = "0.17.1"
[package.extras] [package.extras]
all = ["requests (>=2.24.0,<3.0.0)", "jinja2 (>=2.11.2,<4.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "itsdangerous (>=1.1.0,<3.0.0)", "pyyaml (>=5.3.1,<6.0.0)", "ujson (>=4.0.1,<5.0.0)", "orjson (>=3.2.1,<4.0.0)", "email_validator (>=1.1.1,<2.0.0)", "uvicorn[standard] (>=0.12.0,<0.16.0)"] all = ["requests (>=2.24.0,<3.0.0)", "jinja2 (>=2.11.2,<4.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "itsdangerous (>=1.1.0,<3.0.0)", "pyyaml (>=5.3.1,<6.0.0)", "ujson (>=4.0.1,<5.0.0)", "orjson (>=3.2.1,<4.0.0)", "email_validator (>=1.1.1,<2.0.0)", "uvicorn[standard] (>=0.12.0,<0.16.0)"]
dev = ["python-jose[cryptography] (>=3.3.0,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "autoflake (>=1.4.0,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "uvicorn[standard] (>=0.12.0,<0.16.0)"] dev = ["python-jose[cryptography] (>=3.3.0,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "autoflake (>=1.4.0,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "uvicorn[standard] (>=0.12.0,<0.16.0)"]
doc = ["mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=7.1.9,<8.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.3.0)", "typer-cli (>=0.0.12,<0.0.13)", "pyyaml (>=5.3.1,<6.0.0)"] doc = ["mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.3.0)", "typer-cli (>=0.0.12,<0.0.13)", "pyyaml (>=5.3.1,<6.0.0)"]
test = ["pytest (>=6.2.4,<7.0.0)", "pytest-cov (>=2.12.0,<4.0.0)", "mypy (==0.910)", "flake8 (>=3.8.3,<4.0.0)", "black (==21.9b0)", "isort (>=5.0.6,<6.0.0)", "requests (>=2.24.0,<3.0.0)", "httpx (>=0.14.0,<0.19.0)", "email_validator (>=1.1.1,<2.0.0)", "sqlalchemy (>=1.3.18,<1.5.0)", "peewee (>=3.13.3,<4.0.0)", "databases[sqlite] (>=0.3.2,<0.6.0)", "orjson (>=3.2.1,<4.0.0)", "ujson (>=4.0.1,<5.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "flask (>=1.1.2,<3.0.0)", "anyio[trio] (>=3.2.1,<4.0.0)", "types-ujson (==0.1.1)", "types-orjson (==3.6.0)", "types-dataclasses (==0.1.7)"] test = ["pytest (>=6.2.4,<7.0.0)", "pytest-cov (>=2.12.0,<4.0.0)", "mypy (==0.910)", "flake8 (>=3.8.3,<4.0.0)", "black (==21.9b0)", "isort (>=5.0.6,<6.0.0)", "requests (>=2.24.0,<3.0.0)", "httpx (>=0.14.0,<0.19.0)", "email_validator (>=1.1.1,<2.0.0)", "sqlalchemy (>=1.3.18,<1.5.0)", "peewee (>=3.13.3,<4.0.0)", "databases[sqlite] (>=0.3.2,<0.6.0)", "orjson (>=3.2.1,<4.0.0)", "ujson (>=4.0.1,<5.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "flask (>=1.1.2,<3.0.0)", "anyio[trio] (>=3.2.1,<4.0.0)", "types-ujson (==0.1.1)", "types-orjson (==3.6.0)", "types-dataclasses (==0.1.7)"]
[[package]] [[package]]
@ -564,7 +564,7 @@ jinja2 = "*"
[[package]] [[package]]
name = "loguru" name = "loguru"
version = "0.5.3" version = "0.6.0"
description = "Python logging made (stupidly) simple" description = "Python logging made (stupidly) simple"
category = "main" category = "main"
optional = false optional = false
@ -575,7 +575,7 @@ colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""}
win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""}
[package.extras] [package.extras]
dev = ["codecov (>=2.0.15)", "colorama (>=0.3.4)", "flake8 (>=3.7.7)", "tox (>=3.9.0)", "tox-travis (>=0.12)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "Sphinx (>=2.2.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "black (>=19.10b0)", "isort (>=5.1.1)"] dev = ["colorama (>=0.3.4)", "docutils (==0.16)", "flake8 (>=3.7.7)", "tox (>=3.9.0)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "black (>=19.10b0)", "isort (>=5.1.1)", "Sphinx (>=4.1.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)"]
[[package]] [[package]]
name = "markupsafe" name = "markupsafe"
@ -614,7 +614,7 @@ python-versions = "*"
[[package]] [[package]]
name = "nb-cli" name = "nb-cli"
version = "0.6.5" version = "0.6.6"
description = "CLI for nonebot2" description = "CLI for nonebot2"
category = "dev" category = "dev"
optional = false optional = false
@ -628,7 +628,7 @@ httpx = ">=0.18.0,<1.0.0"
nonebot2 = ">=2.0.0-beta.1,<3.0.0" nonebot2 = ">=2.0.0-beta.1,<3.0.0"
prompt-toolkit = ">=3.0.19,<4.0.0" prompt-toolkit = ">=3.0.19,<4.0.0"
pyfiglet = ">=0.8.post1,<0.9" pyfiglet = ">=0.8.post1,<0.9"
tomlkit = ">=0.7.0,<0.8.0" tomlkit = ">=0.9.0,<0.10.0"
wcwidth = ">=0.2.5,<0.3.0" wcwidth = ">=0.2.5,<0.3.0"
[package.extras] [package.extras]
@ -679,26 +679,26 @@ nonebot2 = ">=2.0.0.a16,<3.0.0"
[[package]] [[package]]
name = "nonebot2" name = "nonebot2"
version = "2.0.0b1" version = "2.0.0b2"
description = "An asynchronous python bot framework." description = "An asynchronous python bot framework."
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7.3,<4.0.0" python-versions = ">=3.7.3,<4.0.0"
[package.dependencies] [package.dependencies]
fastapi = ">=0.70.0,<0.71.0" fastapi = ">=0.73.0,<0.74.0"
loguru = ">=0.5.1,<0.6.0" loguru = ">=0.6.0,<0.7.0"
pydantic = {version = ">=1.9.0,<1.10.0", extras = ["dotenv"]} pydantic = {version = ">=1.9.0,<1.10.0", extras = ["dotenv"]}
pygtrie = ">=2.4.1,<3.0.0" pygtrie = ">=2.4.1,<3.0.0"
tomlkit = ">=0.7.0,<0.8.0" tomlkit = ">=0.9.0,<0.10.0"
typing-extensions = ">=3.10.0,<5.0.0" typing-extensions = ">=3.10.0,<5.0.0"
uvicorn = {version = ">=0.15.0,<0.16.0", extras = ["standard"]} uvicorn = {version = ">=0.17.0,<0.18.0", extras = ["standard"]}
yarl = ">=1.7.2,<2.0.0" yarl = ">=1.7.2,<2.0.0"
[package.extras] [package.extras]
quart = ["Quart (>=0.16.0,<0.17.0)"] quart = ["Quart (>=0.16.0,<0.17.0)"]
all = ["Quart (>=0.16.0,<0.17.0)", "websockets (>=9.1)", "aiohttp[speedups] (>=3.7.4,<4.0.0)", "httpx[http2] (>=0.20.0,<1.0.0)"] all = ["Quart (>=0.16.0,<0.17.0)", "websockets (>=10.0,<11.0)", "aiohttp[speedups] (>=3.7.4,<4.0.0)", "httpx[http2] (>=0.20.0,<1.0.0)"]
websockets = ["websockets (>=9.1)"] websockets = ["websockets (>=10.0,<11.0)"]
aiohttp = ["aiohttp[speedups] (>=3.7.4,<4.0.0)"] aiohttp = ["aiohttp[speedups] (>=3.7.4,<4.0.0)"]
httpx = ["httpx[http2] (>=0.20.0,<1.0.0)"] httpx = ["httpx[http2] (>=0.20.0,<1.0.0)"]
@ -1183,7 +1183,7 @@ tests = ["pytest", "typeguard", "pygments", "littleutils"]
[[package]] [[package]]
name = "starlette" name = "starlette"
version = "0.16.0" version = "0.17.1"
description = "The little ASGI library that shines." description = "The little ASGI library that shines."
category = "main" category = "main"
optional = false optional = false
@ -1193,7 +1193,7 @@ python-versions = ">=3.6"
anyio = ">=3.0.0,<4" anyio = ">=3.0.0,<4"
[package.extras] [package.extras]
full = ["itsdangerous", "jinja2", "python-multipart", "pyyaml", "requests", "graphene"] full = ["itsdangerous", "jinja2", "python-multipart", "pyyaml", "requests"]
[[package]] [[package]]
name = "text-unidecode" name = "text-unidecode"
@ -1229,11 +1229,11 @@ python-versions = ">=3.6"
[[package]] [[package]]
name = "tomlkit" name = "tomlkit"
version = "0.7.2" version = "0.9.2"
description = "Style preserving TOML library" description = "Style preserving TOML library"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" python-versions = ">=3.6,<4.0"
[[package]] [[package]]
name = "traitlets" name = "traitlets"
@ -1293,26 +1293,26 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
[[package]] [[package]]
name = "uvicorn" name = "uvicorn"
version = "0.15.0" version = "0.17.5"
description = "The lightning-fast ASGI server." description = "The lightning-fast ASGI server."
category = "main" category = "main"
optional = false optional = false
python-versions = "*" python-versions = ">=3.7"
[package.dependencies] [package.dependencies]
asgiref = ">=3.4.0" asgiref = ">=3.4.0"
click = ">=7.0" click = ">=7.0"
colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""} colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""}
h11 = ">=0.8" h11 = ">=0.8"
httptools = {version = ">=0.2.0,<0.3.0", optional = true, markers = "extra == \"standard\""} httptools = {version = ">=0.2.0,<0.4.0", optional = true, markers = "extra == \"standard\""}
python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
PyYAML = {version = ">=5.1", optional = true, markers = "extra == \"standard\""} PyYAML = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\" and extra == \"standard\""} uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
watchgod = {version = ">=0.6", optional = true, markers = "extra == \"standard\""} watchgod = {version = ">=0.6", optional = true, markers = "extra == \"standard\""}
websockets = {version = ">=9.1", optional = true, markers = "extra == \"standard\""} websockets = {version = ">=10.0", optional = true, markers = "extra == \"standard\""}
[package.extras] [package.extras]
standard = ["websockets (>=9.1)", "httptools (>=0.2.0,<0.3.0)", "watchgod (>=0.6)", "python-dotenv (>=0.13)", "PyYAML (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "colorama (>=0.4)"] standard = ["websockets (>=10.0)", "httptools (>=0.2.0,<0.4.0)", "watchgod (>=0.6)", "python-dotenv (>=0.13)", "PyYAML (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "colorama (>=0.4)"]
[[package]] [[package]]
name = "uvloop" name = "uvloop"
@ -1395,7 +1395,7 @@ multidict = ">=4.0"
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.9" python-versions = "^3.9"
content-hash = "c67bc1707866ddff4ec0a895755734ff30821321f78a82a4038a33418723bc97" content-hash = "2f409abbd0b4f5a528a4dc49e3f4837a4fe86dcbb26ae0a225037520f94b3101"
[metadata.files] [metadata.files]
aiofiles = [ aiofiles = [
@ -1568,8 +1568,8 @@ expiringdict = [
{file = "expiringdict-1.2.1.tar.gz", hash = "sha256:fe2ba427220425c3c8a3d29f6d2e2985bcee323f8bcd4021e68ebefbd90d8250"}, {file = "expiringdict-1.2.1.tar.gz", hash = "sha256:fe2ba427220425c3c8a3d29f6d2e2985bcee323f8bcd4021e68ebefbd90d8250"},
] ]
fastapi = [ fastapi = [
{file = "fastapi-0.70.1-py3-none-any.whl", hash = "sha256:5367226c7bcd7bfb2e17edaf225fd9a983095b1372281e9a3eb661336fb93748"}, {file = "fastapi-0.73.0-py3-none-any.whl", hash = "sha256:f0a618aff5f6942862f2d3f20f39b1c037e33314d1b8207fd1c3a2cca76dfd8c"},
{file = "fastapi-0.70.1.tar.gz", hash = "sha256:21d03979b5336375c66fa5d1f3126c6beca650d5d2166fbb78345a30d33c8d06"}, {file = "fastapi-0.73.0.tar.gz", hash = "sha256:dcfee92a7f9a72b5d4b7ca364bd2b009f8fc10d95ed5769be20e94f39f7e5a15"},
] ]
feedparser = [ feedparser = [
{file = "feedparser-6.0.8-py3-none-any.whl", hash = "sha256:1b7f57841d9cf85074deb316ed2c795091a238adb79846bc46dccdaf80f9c59a"}, {file = "feedparser-6.0.8-py3-none-any.whl", hash = "sha256:1b7f57841d9cf85074deb316ed2c795091a238adb79846bc46dccdaf80f9c59a"},
@ -1696,8 +1696,8 @@ jinja2-time = [
{file = "jinja2_time-0.2.0-py2.py3-none-any.whl", hash = "sha256:d3eab6605e3ec8b7a0863df09cc1d23714908fa61aa6986a845c20ba488b4efa"}, {file = "jinja2_time-0.2.0-py2.py3-none-any.whl", hash = "sha256:d3eab6605e3ec8b7a0863df09cc1d23714908fa61aa6986a845c20ba488b4efa"},
] ]
loguru = [ loguru = [
{file = "loguru-0.5.3-py3-none-any.whl", hash = "sha256:f8087ac396b5ee5f67c963b495d615ebbceac2796379599820e324419d53667c"}, {file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"},
{file = "loguru-0.5.3.tar.gz", hash = "sha256:b28e72ac7a98be3d28ad28570299a393dfcd32e5e3f6a353dec94675767b6319"}, {file = "loguru-0.6.0.tar.gz", hash = "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c"},
] ]
markupsafe = [ markupsafe = [
{file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"},
@ -1853,8 +1853,8 @@ mypy-extensions = [
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
] ]
nb-cli = [ nb-cli = [
{file = "nb-cli-0.6.5.tar.gz", hash = "sha256:4fba1726419a429e14371c293d2c4ffdc4544f333fead2944febf9692f927774"}, {file = "nb-cli-0.6.6.tar.gz", hash = "sha256:501a747dda00b2d384421634a98b136d9976d12d950d54f1e2bb3c71236ffa73"},
{file = "nb_cli-0.6.5-py3-none-any.whl", hash = "sha256:f19026c9f90b9edeaab8fe05db828f570005ce7baa4f49019ee1276f99754ac3"}, {file = "nb_cli-0.6.6-py3-none-any.whl", hash = "sha256:72a3929e0de4405f5dee7a43cd5358065b36b39125bc99d7dbb1d672bf7f7713"},
] ]
nodeenv = [ nodeenv = [
{file = "nodeenv-1.6.0-py2.py3-none-any.whl", hash = "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"}, {file = "nodeenv-1.6.0-py2.py3-none-any.whl", hash = "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"},
@ -1873,8 +1873,8 @@ nonebot-plugin-help = [
{file = "nonebot_plugin_help-0.1.5-py3-none-any.whl", hash = "sha256:1c4bb626feb202515f47311e3ca9872ab6c0db5e935bc9561325fcc1a2591511"}, {file = "nonebot_plugin_help-0.1.5-py3-none-any.whl", hash = "sha256:1c4bb626feb202515f47311e3ca9872ab6c0db5e935bc9561325fcc1a2591511"},
] ]
nonebot2 = [ nonebot2 = [
{file = "nonebot2-2.0.0b1-py3-none-any.whl", hash = "sha256:76ee4271a0ba9b1fbdcb34c50a23df391bed00d5d32d63b7fd018685de8130a4"}, {file = "nonebot2-2.0.0b2-py3-none-any.whl", hash = "sha256:8166490311b607f8fbf5e31934b005e29f6d39ff222a6771ec36c9456ec337ec"},
{file = "nonebot2-2.0.0b1.tar.gz", hash = "sha256:e23b6656943738a9f8559e20ac51a8c3af799a2eea01e3e2188be01959f36455"}, {file = "nonebot2-2.0.0b2.tar.gz", hash = "sha256:2950f27a62f2a98b2abf3128c19d898a24c2867e70fb5c6af231eadf558b18a8"},
] ]
nonebug = [ nonebug = [
{file = "nonebug-0.2.0-py3-none-any.whl", hash = "sha256:aa0f639f3fc039803640a952b1c12088e8b1ec5a30d1632e43301f215f96de22"}, {file = "nonebug-0.2.0-py3-none-any.whl", hash = "sha256:aa0f639f3fc039803640a952b1c12088e8b1ec5a30d1632e43301f215f96de22"},
@ -2151,8 +2151,8 @@ stack-data = [
{file = "stack_data-0.1.4.tar.gz", hash = "sha256:7769ed2482ce0030e00175dd1bf4ef1e873603b6ab61cd3da443b410e64e9477"}, {file = "stack_data-0.1.4.tar.gz", hash = "sha256:7769ed2482ce0030e00175dd1bf4ef1e873603b6ab61cd3da443b410e64e9477"},
] ]
starlette = [ starlette = [
{file = "starlette-0.16.0-py3-none-any.whl", hash = "sha256:38eb24bf705a2c317e15868e384c1b8a12ca396e5a3c3a003db7e667c43f939f"}, {file = "starlette-0.17.1-py3-none-any.whl", hash = "sha256:26a18cbda5e6b651c964c12c88b36d9898481cd428ed6e063f5f29c418f73050"},
{file = "starlette-0.16.0.tar.gz", hash = "sha256:e1904b5d0007aee24bdd3c43994be9b3b729f4f58e740200de1d623f8c3a8870"}, {file = "starlette-0.17.1.tar.gz", hash = "sha256:57eab3cc975a28af62f6faec94d355a410634940f10b30d68d31cb5ec1b44ae8"},
] ]
text-unidecode = [ text-unidecode = [
{file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"},
@ -2171,8 +2171,8 @@ tomli = [
{file = "tomli-1.2.3.tar.gz", hash = "sha256:05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f"}, {file = "tomli-1.2.3.tar.gz", hash = "sha256:05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f"},
] ]
tomlkit = [ tomlkit = [
{file = "tomlkit-0.7.2-py2.py3-none-any.whl", hash = "sha256:173ad840fa5d2aac140528ca1933c29791b79a374a0861a80347f42ec9328117"}, {file = "tomlkit-0.9.2-py3-none-any.whl", hash = "sha256:daf4f9c5f2fbf6b861d6adfc51940b98dee36c13e1d88749a6dc9fb280fff304"},
{file = "tomlkit-0.7.2.tar.gz", hash = "sha256:d7a454f319a7e9bd2e249f239168729327e4dd2d27b17dc68be264ad1ce36754"}, {file = "tomlkit-0.9.2.tar.gz", hash = "sha256:ebd982d61446af95a1e082b103e250cb9e6d152eae2581d4a07d31a70b34ab0f"},
] ]
traitlets = [ traitlets = [
{file = "traitlets-5.1.1-py3-none-any.whl", hash = "sha256:2d313cc50a42cd6c277e7d7dc8d4d7fedd06a2c215f78766ae7b1a66277e0033"}, {file = "traitlets-5.1.1-py3-none-any.whl", hash = "sha256:2d313cc50a42cd6c277e7d7dc8d4d7fedd06a2c215f78766ae7b1a66277e0033"},
@ -2195,8 +2195,8 @@ urllib3 = [
{file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"}, {file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"},
] ]
uvicorn = [ uvicorn = [
{file = "uvicorn-0.15.0-py3-none-any.whl", hash = "sha256:17f898c64c71a2640514d4089da2689e5db1ce5d4086c2d53699bf99513421c1"}, {file = "uvicorn-0.17.5-py3-none-any.whl", hash = "sha256:8adddf629b79857b48b999ae1b14d6c92c95d4d7840bd86461f09bee75f1653e"},
{file = "uvicorn-0.15.0.tar.gz", hash = "sha256:d9a3c0dd1ca86728d3e235182683b4cf94cd53a867c288eaeca80ee781b2caff"}, {file = "uvicorn-0.17.5.tar.gz", hash = "sha256:c04a9c069111489c324f427501b3840d306c6b91a77b00affc136a840a3f45f1"},
] ]
uvloop = [ uvloop = [
{file = "uvloop-0.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d"}, {file = "uvloop-0.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d"},

View File

@ -24,7 +24,7 @@ classifiers = [
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.9" python = "^3.9"
nonebot2 = "^2.0.0-beta.1" nonebot2 = "^2.0.0-beta.2"
httpx = ">=0.16.1 <1.0.0" httpx = ">=0.16.1 <1.0.0"
bs4 = "^0.0.1" bs4 = "^0.0.1"
tinydb = "^4.3.0" tinydb = "^4.3.0"
@ -49,7 +49,7 @@ nonebug = "^0.2.0"
black = "^22.1.0" black = "^22.1.0"
isort = "^5.10.1" isort = "^5.10.1"
pre-commit = "^2.17.0" pre-commit = "^2.17.0"
nb-cli = "^0.6.5" nb-cli = "^0.6.6"
[build-system] [build-system]
requires = ["poetry>=0.12"] requires = ["poetry>=0.12"]

View File

@ -10,7 +10,6 @@ from nonebot.adapters.onebot.v11 import Bot
from nonebot.adapters.onebot.v11.event import GroupMessageEvent, PrivateMessageEvent from nonebot.adapters.onebot.v11.event import GroupMessageEvent, PrivateMessageEvent
from nonebot.drivers.fastapi import Driver from nonebot.drivers.fastapi import Driver
from nonebot.log import logger from nonebot.log import logger
from nonebot.params import State
from nonebot.rule import to_me from nonebot.rule import to_me
from nonebot.typing import T_State from nonebot.typing import T_State
@ -152,9 +151,7 @@ if (STATIC_PATH / "index.html").exists():
get_token = on_command("后台管理", rule=to_me(), priority=5) get_token = on_command("后台管理", rule=to_me(), priority=5)
@get_token.handle() @get_token.handle()
async def send_token( async def send_token(bot: "Bot", event: PrivateMessageEvent, state: T_State):
bot: "Bot", event: PrivateMessageEvent, state: T_State = State()
):
token = tm.get_user_token((event.get_user_id(), event.sender.nickname)) token = tm.get_user_token((event.get_user_id(), event.sender.nickname))
await get_token.finish(f"请访问: {plugin_config.bison_outer_url}auth/{token}") await get_token.finish(f"请访问: {plugin_config.bison_outer_url}auth/{token}")

View File

@ -1,12 +1,12 @@
from typing import Type from typing import Type
from nonebot import on_command from nonebot import on_command
from nonebot.adapters._event import Event as AbstractEvent from nonebot.adapters import Event as AbstractEvent
from nonebot.adapters.onebot.v11 import Bot, Event from nonebot.adapters.onebot.v11 import Bot, Event
from nonebot.adapters.onebot.v11.message import Message from nonebot.adapters.onebot.v11.message import Message
from nonebot.adapters.onebot.v11.permission import GROUP_ADMIN, GROUP_OWNER from nonebot.adapters.onebot.v11.permission import GROUP_ADMIN, GROUP_OWNER
from nonebot.matcher import Matcher from nonebot.matcher import Matcher
from nonebot.params import Depends, State from nonebot.params import Depends
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from nonebot.rule import to_me from nonebot.rule import to_me
from nonebot.typing import T_State from nonebot.typing import T_State
@ -42,7 +42,7 @@ async def send_help():
def do_add_sub(add_sub: Type[Matcher]): def do_add_sub(add_sub: Type[Matcher]):
@add_sub.handle() @add_sub.handle()
async def init_promote(state: T_State = State()): async def init_promote(state: T_State):
state["_prompt"] = ( state["_prompt"] = (
"请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n"
+ "".join( + "".join(
@ -56,7 +56,7 @@ def do_add_sub(add_sub: Type[Matcher]):
+ "要查看全部平台请输入:“全部”" + "要查看全部平台请输入:“全部”"
) )
async def parse_platform(event: AbstractEvent, state: T_State = State()) -> None: async def parse_platform(event: AbstractEvent, state: T_State) -> None:
if not isinstance(state["platform"], Message): if not isinstance(state["platform"], Message):
return return
platform = str(event.get_message()).strip() platform = str(event.get_message()).strip()
@ -76,7 +76,7 @@ def do_add_sub(add_sub: Type[Matcher]):
@add_sub.got( @add_sub.got(
"platform", _gen_prompt_template("{_prompt}"), [Depends(parse_platform)] "platform", _gen_prompt_template("{_prompt}"), [Depends(parse_platform)]
) )
async def init_id(state: T_State = State()): async def init_id(state: T_State):
if platform_manager[state["platform"]].has_target: if platform_manager[state["platform"]].has_target:
state[ state[
"_prompt" "_prompt"
@ -87,7 +87,7 @@ def do_add_sub(add_sub: Type[Matcher]):
Target("") Target("")
) )
async def parse_id(event: AbstractEvent, state: T_State = State()): async def parse_id(event: AbstractEvent, state: T_State):
if not isinstance(state["id"], Message): if not isinstance(state["id"], Message):
return return
target = str(event.get_message()).strip() target = str(event.get_message()).strip()
@ -101,7 +101,7 @@ def do_add_sub(add_sub: Type[Matcher]):
await add_sub.reject("id输入错误") await add_sub.reject("id输入错误")
@add_sub.got("id", _gen_prompt_template("{_prompt}"), [Depends(parse_id)]) @add_sub.got("id", _gen_prompt_template("{_prompt}"), [Depends(parse_id)])
async def init_cat(state: T_State = State()): async def init_cat(state: T_State):
if not platform_manager[state["platform"]].categories: if not platform_manager[state["platform"]].categories:
state["cats"] = [] state["cats"] = []
return return
@ -109,7 +109,7 @@ def do_add_sub(add_sub: Type[Matcher]):
" ".join(list(platform_manager[state["platform"]].categories.values())) " ".join(list(platform_manager[state["platform"]].categories.values()))
) )
async def parser_cats(event: AbstractEvent, state: T_State = State()): async def parser_cats(event: AbstractEvent, state: T_State):
if not isinstance(state["cats"], Message): if not isinstance(state["cats"], Message):
return return
res = [] res = []
@ -120,13 +120,13 @@ def do_add_sub(add_sub: Type[Matcher]):
state["cats"] = res state["cats"] = res
@add_sub.got("cats", _gen_prompt_template("{_prompt}"), [Depends(parser_cats)]) @add_sub.got("cats", _gen_prompt_template("{_prompt}"), [Depends(parser_cats)])
async def init_tag(state: T_State = State()): async def init_tag(state: T_State):
if not platform_manager[state["platform"]].enable_tag: if not platform_manager[state["platform"]].enable_tag:
state["tags"] = [] state["tags"] = []
return return
state["_prompt"] = '请输入要订阅的tag订阅所有tag输入"全部标签"' state["_prompt"] = '请输入要订阅的tag订阅所有tag输入"全部标签"'
async def parser_tags(event: AbstractEvent, state: T_State = State()): async def parser_tags(event: AbstractEvent, state: T_State):
if not isinstance(state["tags"], Message): if not isinstance(state["tags"], Message):
return return
if str(event.get_message()).strip() == "全部标签": if str(event.get_message()).strip() == "全部标签":
@ -135,7 +135,7 @@ def do_add_sub(add_sub: Type[Matcher]):
state["tags"] = str(event.get_message()).strip().split() state["tags"] = str(event.get_message()).strip().split()
@add_sub.got("tags", _gen_prompt_template("{_prompt}"), [Depends(parser_tags)]) @add_sub.got("tags", _gen_prompt_template("{_prompt}"), [Depends(parser_tags)])
async def add_sub_process(event: Event, state: T_State = State()): async def add_sub_process(event: Event, state: T_State):
config = Config() config = Config()
config.add_subscribe( config.add_subscribe(
state.get("_user_id") or event.group_id, state.get("_user_id") or event.group_id,
@ -151,7 +151,7 @@ def do_add_sub(add_sub: Type[Matcher]):
def do_query_sub(query_sub: Type[Matcher]): def do_query_sub(query_sub: Type[Matcher]):
@query_sub.handle() @query_sub.handle()
async def _(event: Event, state: T_State = State()): async def _(event: Event, state: T_State):
config: Config = Config() config: Config = Config()
sub_list = config.list_subscribe( sub_list = config.list_subscribe(
state.get("_user_id") or event.group_id, "group" state.get("_user_id") or event.group_id, "group"
@ -176,7 +176,7 @@ def do_query_sub(query_sub: Type[Matcher]):
def do_del_sub(del_sub: Type[Matcher]): def do_del_sub(del_sub: Type[Matcher]):
@del_sub.handle() @del_sub.handle()
async def send_list(bot: Bot, event: Event, state: T_State = State()): async def send_list(bot: Bot, event: Event, state: T_State):
config: Config = Config() config: Config = Config()
sub_list = config.list_subscribe( sub_list = config.list_subscribe(
state.get("_user_id") or event.group_id, "group" state.get("_user_id") or event.group_id, "group"
@ -205,7 +205,7 @@ def do_del_sub(del_sub: Type[Matcher]):
await bot.send(event=event, message=Message(await parse_text(res))) await bot.send(event=event, message=Message(await parse_text(res)))
@del_sub.receive() @del_sub.receive()
async def do_del(event: Event, state: T_State = State()): async def do_del(event: Event, state: T_State):
try: try:
index = int(str(event.get_message()).strip()) index = int(str(event.get_message()).strip())
config = Config() config = Config()
@ -220,7 +220,7 @@ def do_del_sub(del_sub: Type[Matcher]):
await del_sub.finish("删除成功") await del_sub.finish("删除成功")
async def parse_group_number(event: AbstractEvent, state: T_State = State()): async def parse_group_number(event: AbstractEvent, state: T_State):
if not isinstance(state["_user_id"], Message): if not isinstance(state["_user_id"], Message):
return return
state["_user_id"] = int(str(event.get_message())) state["_user_id"] = int(str(event.get_message()))

View File

@ -3,8 +3,8 @@ from typing import Any, Callable, Literal, NamedTuple, NewType
RawPost = NewType("RawPost", Any) RawPost = NewType("RawPost", Any)
Target = NewType("Target", str) Target = NewType("Target", str)
Category = NewType("Category", int) Category = int
Tag = NewType("Tag", str) Tag = str
@dataclass(eq=True, frozen=True) @dataclass(eq=True, frozen=True)

View File

@ -12,6 +12,7 @@ async def app(nonebug_init: None, tmp_path: Path, monkeypatch: pytest.MonkeyPatc
config = nonebot.get_driver().config config = nonebot.get_driver().config
config.bison_config_path = str(tmp_path) config.bison_config_path = str(tmp_path)
config.command_start = {""}
return App(monkeypatch) return App(monkeypatch)

View File

@ -0,0 +1 @@
{"ok":1,"data":{"isVideoCoverStyle":1,"isStarStyle":0,"userInfo":{"id":6279793937,"screen_name":"\u660e\u65e5\u65b9\u821fArknights","profile_image_url":"https:\/\/tvax4.sinaimg.cn\/crop.0.0.756.756.180\/006QZngZly8gdj05mufr9j30l00l0dq4.jpg?KID=imgbed,tva&Expires=1645010805&ssig=POD2VKV4LB","profile_url":"https:\/\/m.weibo.cn\/u\/6279793937?uid=6279793937&luicode=10000011&lfid=1005056279793937","statuses_count":1553,"verified":true,"verified_type":2,"verified_type_ext":50,"verified_reason":"\u4e0a\u6d77\u9e70\u89d2\u7f51\u7edc\u79d1\u6280\u6709\u9650\u516c\u53f8","close_blue_v":false,"description":"\u300a\u660e\u65e5\u65b9\u821f\u300b\u5b98\u65b9\u5fae\u535a\uff0c\u6b22\u8fce\u54a8\u8be2\u5ba2\u670dQQ\u670d\u52a1\u53f7\uff1a800830064","gender":"f","mbtype":12,"urank":4,"mbrank":7,"follow_me":false,"following":false,"follow_count":34,"followers_count":"145.5\u4e07","followers_count_str":"145.5\u4e07","cover_image_phone":"https:\/\/wx4.sinaimg.cn\/crop.0.0.640.640.640\/006QZngZly1gq8sa16csgj30u00u0akt.jpg","avatar_hd":"https:\/\/wx4.sinaimg.cn\/orj480\/006QZngZly8gdj05mufr9j30l00l0dq4.jpg","like":false,"like_me":false,"toolbar_menus":[{"type":"link","name":"\u804a\u5929","pic":"http:\/\/h5.sinaimg.cn\/upload\/2015\/06\/12\/2\/toolbar_icon_discuss_default.png","params":{"scheme":"sinaweibo:\/\/messagelist?uid=6279793937&nick=\u660e\u65e5\u65b9\u821fArknights"},"scheme":"https:\/\/passport.weibo.cn\/signin\/welcome?entry=mweibo&r=https%3A%2F%2Fm.weibo.cn%2Fapi%2Fcontainer%2FgetIndex%3Fcontainerid%3D1005056279793937"},{"type":"profile_follow","name":"\u5173\u6ce8","pic":"","params":{"uid":6279793937,"extparams":{"followcardid":"0001980001_6279793937_b2f217e4"}},"userInfo":{"id":6279793937,"idstr":"6279793937","screen_name":"\u660e\u65e5\u65b9\u821fArknights","profile_image_url":"https:\/\/tvax4.sinaimg.cn\/crop.0.0.756.756.50\/006QZngZly8gdj05mufr9j30l00l0dq4.jpg?KID=imgbed,tva&Expires=1645010805&ssig=pKJtZwv%2FHm","following":false,"verified":true,"verified_type":2,"remark":"","avatar_large":"https:\/\/tvax4.sinaimg.cn\/crop.0.0.756.756.180\/006QZngZly8gdj05mufr9j30l00l0dq4.jpg?KID=imgbed,tva&Expires=1645010805&ssig=POD2VKV4LB","avatar_hd":"https:\/\/tvax4.sinaimg.cn\/crop.0.0.756.756.1024\/006QZngZly8gdj05mufr9j30l00l0dq4.jpg?KID=imgbed,tva&Expires=1645010805&ssig=RBGOJz6PB6","verified_type_ext":50,"follow_me":false,"mbtype":12,"mbrank":6,"level":2,"type":1,"story_read_state":-1,"allow_msg":1,"friendships_relation":0,"close_friends_type":0,"special_follow":false}}]},"fans_scheme":"https:\/\/m.weibo.cn\/c\/attention\/visit?showmenu=0&sign=6279793937&source=MQ%3D%3D&role=NA%3D%3D&luicode=10000011&lfid=1005056279793937","follow_scheme":"https:\/\/m.weibo.cn\/c\/attention\/visit?showmenu=0&sign=6279793937&source=MA%3D%3D&role=NA%3D%3D&luicode=10000011&lfid=1005056279793937","tabsInfo":{"selectedTab":1,"tabs":[{"id":1,"tabKey":"profile","must_show":1,"hidden":0,"title":"\u7cbe\u9009","tab_type":"profile","containerid":"2302836279793937"},{"id":2,"tabKey":"weibo","must_show":1,"hidden":0,"title":"\u5fae\u535a","tab_type":"weibo","containerid":"1076036279793937","apipath":"\/profile\/statuses","tab_icon":"https:\/\/h5.sinaimg.cn\/upload\/1059\/799\/2021\/04\/01\/weibotab.png","tab_icon_dark":"https:\/\/h5.sinaimg.cn\/upload\/1059\/799\/2021\/04\/07\/weibotab_dark.png","url":"\/index\/my"},{"id":4,"tabKey":"original_video","must_show":0,"hidden":0,"title":"\u89c6\u9891","tab_type":"video","containerid":"2315676279793937"},{"id":10,"tabKey":"album","must_show":0,"hidden":0,"title":"\u76f8\u518c","tab_type":"album","containerid":"1078036279793937"}]},"profile_ext":"touid:6279793937","scheme":"sinaweibo:\/\/userinfo?uid=6279793937&_T_WM=38226655008&v_p=42&uid=6279793937&luicode=10000011&lfid=1005056279793937","showAppTips":0}}

View File

@ -0,0 +1 @@
{"ok":0,"msg":"\u8fd9\u91cc\u8fd8\u6ca1\u6709\u5185\u5bb9","data":{"cards":[]}}

52
tests/test_config.py Normal file
View File

@ -0,0 +1,52 @@
import typing
import pytest
from nonebug.app import App
if typing.TYPE_CHECKING:
import sys
sys.path.append("./src/plugins")
import nonebot_bison
from nonebot_bison.config import Config
@pytest.fixture
def config(app: App):
from nonebot_bison import config
config.start_up()
return config.Config()
def test_create_and_get(config: "Config", app: App):
from nonebot_bison import types
from nonebot_bison.types import Target
config.add_subscribe(
user="123",
user_type="group",
target="weibo_id",
target_name="weibo_name",
target_type="weibo",
cats=[],
tags=[],
)
confs = config.list_subscribe("123", "group")
assert len(confs) == 1
assert config.target_user_cache["weibo"][Target("weibo_id")] == [
types.User("123", "group")
]
assert confs[0]["cats"] == []
config.update_subscribe(
user="123",
user_type="group",
target="weibo_id",
target_name="weibo_name",
target_type="weibo",
cats=["1"],
tags=[],
)
confs = config.list_subscribe("123", "group")
assert len(confs) == 1
assert confs[0]["cats"] == ["1"]

View File

@ -1,52 +1,103 @@
import typing
import pytest import pytest
import respx
from httpx import Response
from nonebot.adapters.onebot.v11.event import Sender
from nonebot.adapters.onebot.v11.message import MessageSegment
from nonebug.app import App from nonebug.app import App
if typing.TYPE_CHECKING: from .platforms.utils import get_json
import sys from .utils import fake_admin_user, fake_group_message_event
sys.path.append("./src/plugins")
import nonebot_bison @pytest.mark.asyncio
@respx.mock
async def test_add_with_target(app: App):
from nonebot.adapters.onebot.v11.message import Message
from nonebot_bison.config import Config from nonebot_bison.config import Config
from nonebot_bison.config_manager import add_sub_matcher, common_platform
from nonebot_bison.platform import platform_manager
config = Config()
config.user_target.truncate()
@pytest.fixture ak_list_router = respx.get(
def config(app: App): "https://m.weibo.cn/api/container/getIndex?containerid=1005056279793937"
from nonebot_bison import config
config.start_up()
return config.Config()
def test_create_and_get(config: "Config", app: App):
from nonebot_bison import types
from nonebot_bison.types import Target
config.add_subscribe(
user="123",
user_type="group",
target="weibo_id",
target_name="weibo_name",
target_type="weibo",
cats=[],
tags=[],
) )
confs = config.list_subscribe("123", "group") ak_list_router.mock(
assert len(confs) == 1 return_value=Response(200, json=get_json("weibo_ak_profile.json"))
assert config.target_user_cache["weibo"][Target("weibo_id")] == [
types.User("123", "group")
]
assert confs[0]["cats"] == []
config.update_subscribe(
user="123",
user_type="group",
target="weibo_id",
target_name="weibo_name",
target_type="weibo",
cats=["1"],
tags=[],
) )
confs = config.list_subscribe("123", "group") ak_list_bad_router = respx.get(
assert len(confs) == 1 "https://m.weibo.cn/api/container/getIndex?containerid=100505000"
assert confs[0]["cats"] == ["1"] )
ak_list_bad_router.mock(
return_value=Response(200, json=get_json("weibo_err_profile.json"))
)
async with app.test_matcher(add_sub_matcher) as ctx:
bot = ctx.create_bot()
event_1 = fake_group_message_event(
message=Message("添加订阅"),
sender=Sender(card="", nickname="test", role="admin"),
to_me=True,
)
ctx.receive_event(bot, event_1)
ctx.should_pass_rule()
ctx.should_call_send(
event_1,
Message(
"请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n"
+ "".join(
[
"{}{}\n".format(
platform_name, platform_manager[platform_name].name
)
for platform_name in common_platform
]
)
+ "要查看全部平台请输入:“全部”"
),
True,
)
event_2 = fake_group_message_event(
message=Message("全部"), sender=Sender(card="", nickname="test", role="admin")
)
ctx.receive_event(bot, event_2)
ctx.should_rejected()
ctx.should_call_send(
event_2,
(
"全部平台\n"
+ "\n".join(
[
"{}{}".format(platform_name, platform.name)
for platform_name, platform in platform_manager.items()
]
)
),
True,
)
event_3 = fake_group_message_event(
message=Message("weibo"), sender=fake_admin_user
)
ctx.receive_event(bot, event_3)
ctx.should_call_send(
event_3,
Message(
"请输入订阅用户的id详情查阅https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84uid"
),
True,
)
event_4_err = fake_group_message_event(
message=Message("000"), sender=fake_admin_user
)
import ipdb
ipdb.set_trace()
ctx.receive_event(bot, event_4_err)
ctx.should_call_send(event_4_err, "id输入错误", True)
ctx.should_rejected()
event_4_ok = fake_group_message_event(
message=Message("6279793937"), sender=fake_admin_user
)
ctx.receive_event(bot, event_4_ok)
ctx.should_call_send(event_4_ok, "id输入错误", True)

70
tests/utils.py Normal file
View File

@ -0,0 +1,70 @@
from typing import TYPE_CHECKING
from typing_extensions import Literal
if TYPE_CHECKING:
from nonebot.adapters.onebot.v11 import GroupMessageEvent, PrivateMessageEvent
def fake_group_message_event(**field) -> "GroupMessageEvent":
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message
from nonebot.adapters.onebot.v11.event import Sender
from pydantic import create_model
_Fake = create_model("_Fake", __base__=GroupMessageEvent)
class FakeEvent(_Fake):
time: int = 1000000
self_id: int = 1
post_type: Literal["message"] = "message"
sub_type: str = "normal"
user_id: int = 10
message_type: Literal["group"] = "group"
group_id: int = 10000
message_id: int = 1
message: Message = Message("test")
raw_message: str = "test"
font: int = 0
sender: Sender = Sender(
card="",
nickname="test",
role="member",
)
to_me: bool = False
class Config:
extra = "forbid"
return FakeEvent(**field)
def fake_private_message_event(**field) -> "PrivateMessageEvent":
from nonebot.adapters.onebot.v11 import Message, PrivateMessageEvent
from nonebot.adapters.onebot.v11.event import Sender
from pydantic import create_model
_Fake = create_model("_Fake", __base__=PrivateMessageEvent)
class FakeEvent(_Fake):
time: int = 1000000
self_id: int = 1
post_type: Literal["message"] = "message"
sub_type: str = "friend"
user_id: int = 10
message_type: Literal["private"] = "private"
message_id: int = 1
message: Message = Message("test")
raw_message: str = "test"
font: int = 0
sender: Sender = Sender(nickname="test")
to_me: bool = False
class Config:
extra = "forbid"
return FakeEvent(**field)
from nonebot.adapters.onebot.v11.event import Sender
fake_admin_user = Sender(nickname="test", role="admin")