版本更新 (#1666)
* ✨ 父级插件加载 * ✅ 添加测试:更新与添加插件 (#1594) * ✅ 测试更新与添加插件 * ✅ Sourcery建议 * 👷 添加pytest * 🎨 优化代码 * 🐛 bug修复 * 🐛修复添加插件返回403的问题 (#1595) * 完善测试方法 * vscode测试配置 * 重构插件安装过程 * 🎨 修改readme * Update README.md * 🐛 修改bug与版本锁定 * 🐛 修复超级用户对群组功能开关 * 🐛 修复插件商店检查插件更新问题 (#1597) * 🐛 修复插件商店检查插件更新问题 * 🐛 恶意命令检测问题 * 🐛 增加插件状态检查 (#1598) * ✅ 优化测试用例 * 🐛 更改插件更新与安装逻辑 * 🐛 修复更新群组成员信息 * 🎨 代码优化 * 🚀 更新Dockerfile (#1599) * 🎨 更新requirements * ➕ 添加依赖aiocache * ⚡ 添加github镜像 * ✨ 添加仓库目录多获取渠道 * 🐛 修复测试用例 * ✨ 添加API缓存 * 🎨 采取Sourcery建议 * 🐛 文件下载逻辑修改 * 🎨 优化代码 * 🐛 修复插件开关有时出现错误 * ✨ 重构自检ui * 🐛 自检html修正 * 修复签到逻辑bug,并使代码更灵活以适应签到好感度等级配置 (#1606) * 修复签到功能已知问题 * 修复签到功能已知问题 * 修改参数名称 * 修改uid判断 --------- Co-authored-by: HibiKier <45528451+HibiKier@users.noreply.github.com> * 🎨 代码结构优化 * 🐛 私聊时修改插件时删除私聊帮助 * 🐛 过滤父插件 * 🐛 修复自检在ARM上的问题 (#1607) * 🐛 修复自检在ARM上的问题 * ✅ 优化测试 * ✨ 支持mysql,psql,sqlite随机函数 * 🔧 VSCode配置修改 * 🔧 VSCode配置修改 * ✨ 添加金币排行 Co-Authored-By: HibiKier <45528451+HibiKier@users.noreply.github.com> * 📝 修改README Co-Authored-By: HibiKier <45528451+HibiKier@users.noreply.github.com> * 🔨 提取GitHub相关操作 (#1609) * 🔨 提取GitHub相关操作 * 🔨 重构API策略 * ✨ 签到/金币排行限制最大数量 (#1616) * ✨ 签到/金币排行限制最大数量 * 🐛 修复超级用户id获取问题 * 🐛 修复路径解压与挂载 (#1619) * 🐛 修复功能少时zhenxun帮助图片排序问题 (#1620) * 🐛 签到文本适应 (#1622) * 🐛 好感度排行提供默认值 (#1624) * 🎈 优先使用github api (#1625) * ✨ 重构帮助,限制普通用户查询管理插件 (#1626) * 🐛 修复群权限与插件等级匹配 (#1627) * ✨ 当管理员尝试ban真寻时将被反杀 (#1628) * ✨ 群组发言时间检测提供开关配置 (#1630) * 🐳 chore: 支持自动修改版本号 (#1629) * 🎈 perf(github_utils): 支持github url下载遍历 (#1632) * 🎈 perf(github_utils): 支持github url下载遍历 * 🐞 fix(http_utils): 修复一些下载问题 * 🦄 refactor(http_utils): 部分重构 * chore(version): Update version to v0.2.2-e6f17c4 --------- Co-authored-by: AkashiCoin <AkashiCoin@users.noreply.github.com> * 🧪 test(auto_update): 修复测试用例 (#1633) * 🐛 修复商店商品为空时报错 (#1634) * 🐛 修复群权限与插件等级匹配 (#1635) * ✨ message_build支持AtAll (#1639) * 🎈 perf: 使用commit号下载插件 (#1641) * 🎈 perf: 使用commit号下载插件 * chore(version): Update version to v0.2.2-f9c7360 --------- Co-authored-by: AkashiCoin <AkashiCoin@users.noreply.github.com> * 🐳 chore: 修改运行检查触发路径 (#1642) * 🐳 chore: 修改运行检查触发路径 * 🐳 chore: 添加tests目录 * ✨ 重构qq群事件处理 (#1643) * 🐛 签到名称自适应 (#1644) * 🎨 更新README (#1645) * 🐛 fix(http_utils): 流式下载Content-Length错误 (#1647) * 🐛 修复群组中帮助功能状态显示问题 (#1650) * 🐛 修复群欢迎消息设置 (#1651) * 🐛 修复webui下载后首次启动错误 (#1652) * 🐛 修复webui下载后首次启动错误 * chore(version): Update version to v0.2.2-4a8ef85 --------- Co-authored-by: HibiKier <HibiKier@users.noreply.github.com> * ✨ 移除默认图片文件夹:爬 (#1653) * ✨ 安装/移除插件提供插件安装/卸载方法用于插件初始化 (#1654) * ✨ 新增超级用户与管理员帮助模板 (#1655) * ✨ 新增个人信息命令 (#1657) * ✨ 修改个人信息菜单名称 (#1658) * ✨ 新增插件商店api (#1659) * ✨ 新增插件商店api * chore(version): Update version to v0.2.2-7e15f20 --------- Co-authored-by: HibiKier <HibiKier@users.noreply.github.com> * ✨ 将cd,block,count限制复原配置文件 (#1662) * 🎨 修改README (#1663) * 🎨 修改版本号 (#1664) * 🎨 修改requirements (#1665) --------- Co-authored-by: AkashiCoin <l1040186796@gmail.com> Co-authored-by: fanyinrumeng <42991257+fanyinrumeng@users.noreply.github.com> Co-authored-by: AkashiCoin <i@loli.vet> Co-authored-by: Elaga <1728903318@qq.com> Co-authored-by: AkashiCoin <AkashiCoin@users.noreply.github.com> Co-authored-by: HibiKier <HibiKier@users.noreply.github.com>
2
.env.dev
@ -16,6 +16,8 @@ SELF_NICKNAME="小真寻"
|
||||
|
||||
# 数据库配置
|
||||
# 示例: "postgres://user:password@127.0.0.1:5432/database"
|
||||
# 示例: "mysql://user:password@127.0.0.1:3306/database"
|
||||
# 示例: "sqlite:data/db/zhenxun.db" 在data目录下建立db文件夹
|
||||
DB_URL = ""
|
||||
|
||||
# 系统代理
|
||||
|
||||
21
.github/workflows/bot_check.yml
vendored
@ -3,8 +3,16 @@ name: 检查bot是否运行正常
|
||||
on:
|
||||
push:
|
||||
branches: ["dev", "main"]
|
||||
paths:
|
||||
- zhenxun/**
|
||||
- tests/**
|
||||
- bot.py
|
||||
pull_request:
|
||||
branches: ["dev", "main"]
|
||||
paths:
|
||||
- zhenxun/**
|
||||
- tests/**
|
||||
- bot.py
|
||||
|
||||
jobs:
|
||||
bot-check:
|
||||
@ -28,7 +36,14 @@ jobs:
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/pypoetry
|
||||
key: poetry-cache-${{ runner.os }}-${{ steps.setup_python.outputs.python-version }}
|
||||
key: poetry-cache-${{ runner.os }}-${{ steps.setup_python.outputs.python-version }}-${{ hashFiles('pyproject.toml') }}
|
||||
|
||||
- name: Cache playwright cache
|
||||
id: cache-playwright
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: playwright-cache-${{ runner.os }}-${{ steps.setup_python.outputs.python-version }}
|
||||
|
||||
- name: Cache Data cache
|
||||
uses: actions/cache@v3
|
||||
@ -42,7 +57,9 @@ jobs:
|
||||
rm -rf poetry.lock
|
||||
poetry source remove ali
|
||||
poetry install --no-root
|
||||
poetry run pip install pydantic==1.10
|
||||
|
||||
- name: Run tests
|
||||
run: poetry run pytest --cov=zhenxun --cov-report xml
|
||||
|
||||
- name: Check bot run
|
||||
id: bot_check_run
|
||||
|
||||
65
.github/workflows/update_version.yml
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
name: Update Version
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
paths:
|
||||
- zhenxun/**
|
||||
- resources/**
|
||||
- bot.py
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
branches:
|
||||
- main
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
update-version:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Read current version
|
||||
id: read_version
|
||||
run: |
|
||||
version_line=$(grep '__version__' __version__)
|
||||
version=$(echo $version_line | sed -E 's/__version__:\s*v([0-9]+\.[0-9]+\.[0-9]+)(-.+)?/\1/')
|
||||
echo "Current version: $version"
|
||||
echo "current_version=$version" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Check for version file changes
|
||||
id: check_diff
|
||||
run: |
|
||||
if git diff --name-only HEAD~1 HEAD | grep -q '__version__'; then
|
||||
echo "Version file has changes"
|
||||
echo "version_changed=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Version file has no changes"
|
||||
echo "version_changed=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Get commit hash
|
||||
id: get_commit_hash
|
||||
run: echo "commit_hash=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Update version file
|
||||
if: steps.check_diff.outputs.version_changed == 'false'
|
||||
run: |
|
||||
current_version="${{ steps.read_version.outputs.current_version }}"
|
||||
commit_hash="${{ steps.get_commit_hash.outputs.commit_hash }}"
|
||||
new_version="v${current_version}-${commit_hash}"
|
||||
echo "Updating version to: $new_version"
|
||||
echo "__version__: $new_version" > __version__
|
||||
git config --global user.name "${{ github.event.pull_request.user.login }}"
|
||||
git config --global user.email "${{ github.event.pull_request.user.login }}@users.noreply.github.com"
|
||||
git add __version__
|
||||
git remote set-url origin https://github.com/${{ github.event.pull_request.head.repo.full_name }}.git
|
||||
git commit -m "chore(version): Update version to $new_version"
|
||||
git push origin HEAD:${{ github.event.pull_request.head.ref }}
|
||||
|
||||
- name: Check updated version
|
||||
if: steps.check_diff.outputs.version_changed == 'false'
|
||||
run: cat __version__
|
||||
4
.gitignore
vendored
@ -174,11 +174,9 @@ data/
|
||||
/resources/image/prts/
|
||||
/configs/config.py
|
||||
configs/config.yaml
|
||||
./.env
|
||||
./.env.dev
|
||||
plugins/csgo_server/
|
||||
plugins/activity/
|
||||
!/resources/image/genshin/alc/back.png
|
||||
!/data/genshin_alc/
|
||||
.vscode/launch.json
|
||||
/resources/template/my_info
|
||||
plugins_/
|
||||
10
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"charliermarsh.ruff",
|
||||
"esbenp.prettier-vscode",
|
||||
"ms-python.black-formatter",
|
||||
"ms-python.isort",
|
||||
"ms-python.python",
|
||||
"ms-python.vscode-pylance"
|
||||
]
|
||||
}
|
||||
34
.vscode/settings.json
vendored
@ -23,7 +23,37 @@
|
||||
"ujson",
|
||||
"unban",
|
||||
"userinfo",
|
||||
"zhenxun"
|
||||
"zhenxun",
|
||||
"jsdelivr"
|
||||
],
|
||||
"python.analysis.autoImportCompletions": true
|
||||
"python.analysis.autoImportCompletions": true,
|
||||
"python.testing.pytestArgs": ["tests"],
|
||||
"python.testing.unittestEnabled": false,
|
||||
"python.testing.pytestEnabled": true,
|
||||
"[python]": {
|
||||
"editor.defaultFormatter": "charliermarsh.ruff", // 默认使用 Ruff 格式化
|
||||
"editor.wordBasedSuggestions": "allDocuments",
|
||||
"editor.formatOnType": true,
|
||||
"editor.formatOnSave": true, // 保存时自动格式化
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.ruff": "explicit",
|
||||
"source.organizeImports": "explicit"
|
||||
}
|
||||
},
|
||||
"ruff.format.preview": false,
|
||||
"isort.check": true,
|
||||
"ruff.importStrategy": "useBundled",
|
||||
"ruff.organizeImports": false,
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[yaml]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[markdown]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
}
|
||||
}
|
||||
|
||||
11
Dockerfile
@ -6,6 +6,13 @@ WORKDIR /app/zhenxun
|
||||
|
||||
COPY . /app/zhenxun
|
||||
|
||||
RUN apt update && \
|
||||
apt upgrade -y && \
|
||||
apt install -y --no-install-recommends \
|
||||
gcc \
|
||||
g++ && \
|
||||
apt clean
|
||||
|
||||
RUN pip install poetry -i https://mirrors.aliyun.com/pypi/simple/
|
||||
|
||||
RUN poetry install
|
||||
@ -14,6 +21,8 @@ VOLUME /app/zhenxun/data /app/zhenxun/data
|
||||
|
||||
VOLUME /app/zhenxun/resources /app/zhenxun/resources
|
||||
|
||||
VOLUME /app/zhenxun/.env.dev /app/zhenxun/.env.dev
|
||||
|
||||
RUN poetry run playwright install --with-deps chromium
|
||||
|
||||
CMD ["poetry", "run", "python", "bot.py"]
|
||||
CMD ["poetry", "run", "python", "bot.py"]
|
||||
|
||||
136
README.md
@ -28,7 +28,7 @@
|
||||
|
||||
<div align=center>
|
||||
|
||||
## 绪山真寻Bot
|
||||
## 绪山真寻 Bot
|
||||
|
||||
</div>
|
||||
|
||||
@ -39,11 +39,12 @@
|
||||
:tada:喜欢真寻,于是真寻就来了!:tada:
|
||||
|
||||
本项目符合 [OneBot](https://github.com/howmanybots/onebot) 标准,可基于以下项目与机器人框架/平台进行交互
|
||||
| 项目地址 | 平台 | 核心作者 | 备注 |
|
||||
| :---: | :---: | :---: | :---: |
|
||||
| [LLOneBot](https://github.com/LLOneBot/LLOneBot) | NTQQ | linyuchen | 可用 |
|
||||
| [Napcat](https://github.com/NapNeko/NapCatQQ) | NTQQ | NapNeko | 可用 |
|
||||
| [Lagrange.Core](https://github.com/LagrangeDev/Lagrange.Core) | | LagrangeDev/Linwenxuan04 | 可用
|
||||
|
||||
| 项目地址 | 平台 | 核心作者 | 备注 |
|
||||
| :-----------------------------------------------------------: | :--: | :----------------------: | :--: |
|
||||
| [LLOneBot](https://github.com/LLOneBot/LLOneBot) | NTQQ | linyuchen | 可用 |
|
||||
| [Napcat](https://github.com/NapNeko/NapCatQQ) | NTQQ | NapNeko | 可用 |
|
||||
| [Lagrange.Core](https://github.com/LagrangeDev/Lagrange.Core) | | LagrangeDev/Linwenxuan04 | 可用 |
|
||||
|
||||
</div>
|
||||
|
||||
@ -57,8 +58,9 @@
|
||||
|
||||
<div align=center>
|
||||
|
||||
<img width="400" height="400" src="https://raw.githubusercontent.com/HibiKier/zhenxun_bot/main/docs_image/help.png"/>
|
||||
<img width="350" height="350" src="https://raw.githubusercontent.com/HibiKier/zhenxun_bot/main/docs_image/help.png"/>
|
||||
<img width="250" height="500" src="https://raw.githubusercontent.com/HibiKier/zhenxun_bot/main/docs_image/html_help.png"/>
|
||||
<img width="180" height="450" src="https://github.com/HibiKier/zhenxun_bot/blob/dev/docs_image/zhenxun_help.png"/>
|
||||
|
||||
</div>
|
||||
|
||||
@ -66,7 +68,7 @@
|
||||
|
||||
### 1. 体验一下?
|
||||
|
||||
这是一个免费的,版本为dev的zhenxun,你可以通过napcat或拉格朗日等直接连接用于体验与测试
|
||||
这是一个免费的,版本为 dev 的 zhenxun,你可以通过 napcat 或拉格朗日等直接连接用于体验与测试
|
||||
(球球了测试君!)
|
||||
|
||||
```
|
||||
@ -82,16 +84,13 @@ AccessToken: PUBLIC_ZHENXUN_TEST
|
||||
|
||||
“不要害怕,你的背后还有千千万万的 <strong>伙伴</strong> 啊!”
|
||||
|
||||
| 项目名称 | 主要用途 | 仓库作者 | 备注 |
|
||||
| :-----------------------------------------------------------------------------------------------: | :------: | :-------------------------------------------: | :-------------------------------------------------------------: |
|
||||
| [插件库](https://github.com/zhenxun-org/zhenxun_bot_plugins) | 插件 | [zhenxun-org](https://github.com/zhenxun-org) | 原plugins文件夹插件 |
|
||||
| [插件索引库](https://github.com/zhenxun-org/zhenxun_bot_plugins_index) | 插件 | [zhenxun-org](https://github.com/zhenxun-org) | 扩展插件索引库 |
|
||||
| [WebUi](https://github.com/HibiKier/zhenxun_bot_webui) | 管理 | [hibikier](https://github.com/HibiKier) | 基于真寻WebApi的webui实现 |
|
||||
| [一键安装](https://github.com/zhenxun-org/zhenxun_bot-deploy) | 安装 | [AkashiCoin](https://github.com/AkashiCoin) | 新版本未测试 |
|
||||
| [Docker单机版](https://github.com/Sakuracio/zhenxun_bot_docker) | 安装 | [zhenxun-org](https://github.com/zhenxun-org) | 新版本未测试 |
|
||||
| [Docker全量版](https://shields.io/badge/GITHUB-SinKy--Yan-4476AF?logo=github&style=for-the-badge) | 安装 | [zhenxun-org](https://github.com/zhenxun-org) | 包含 真寻Bot PostgreSQL数据库 go-cqhttp webui等(新版本未测试) |
|
||||
|
||||
PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能无法正常启动全量版容器**
|
||||
| 项目名称 | 主要用途 | 仓库作者 | 备注 |
|
||||
| :--------------------------------------------------------------------: | :------: | :-------------------------------------------------: | :---------------------------: |
|
||||
| [插件库](https://github.com/zhenxun-org/zhenxun_bot_plugins) | 插件 | [zhenxun-org](https://github.com/zhenxun-org) | 原 plugins 文件夹插件 |
|
||||
| [插件索引库](https://github.com/zhenxun-org/zhenxun_bot_plugins_index) | 插件 | [zhenxun-org](https://github.com/zhenxun-org) | 扩展插件索引库 |
|
||||
| [一键安装](https://github.com/soloxiaoye2022/zhenxun_bot-deploy) | 安装 | [soloxiaoye2022](https://github.com/soloxiaoye2022) | 第三方 |
|
||||
| [WebUi](https://github.com/HibiKier/zhenxun_bot_webui) | 管理 | [hibikier](https://github.com/HibiKier) | 基于真寻 WebApi 的 webui 实现 |
|
||||
| [安卓 app(WebUi)](https://github.com/YuS1aN/zhenxun_bot_android_ui) | 安装 | [YuS1aN](https://github.com/YuS1aN) | 第三方 |
|
||||
|
||||
<details>
|
||||
<summary> <strong> WebUI </strong>后台示例图 </summary>
|
||||
@ -113,10 +112,10 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可
|
||||
## ~~来点优点?~~ 可爱难道还不够吗
|
||||
|
||||
- 实现了许多功能,且提供了大量功能管理命令
|
||||
- 通过Config配置项将所有插件配置统计保存至config.yaml,利于统一用户修改
|
||||
- 方便增删插件,原生nonebot2 matcher,不需要额外修改,仅仅通过简单的配置属性就可以生成`帮助图片`和`帮助信息`
|
||||
- 提供了cd,阻塞,每日次数等限制,仅仅通过简单的属性就可以生成一个限制,例如:`PluginCdBlock` 等
|
||||
- **..... 更多详细请通过`传送门`查看文档!**
|
||||
- 通过 Config 配置项将所有插件配置统计保存至 config.yaml,利于统一用户修改
|
||||
- 方便增删插件,原生 nonebot2 matcher,不需要额外修改,仅仅通过简单的配置属性就可以生成`帮助图片`和`帮助信息`
|
||||
- 提供了 cd,阻塞,每日次数等限制,仅仅通过简单的属性就可以生成一个限制,例如:`PluginCdBlock` 等
|
||||
- **..... 更多详细请通过[[传送门](https://hibikier.github.io/zhenxun_bot/)]查看文档!**
|
||||
|
||||
## 简单部署
|
||||
|
||||
@ -135,9 +134,6 @@ poetry install # 安装依赖
|
||||
poetry shell # 进入虚拟环境
|
||||
python bot.py
|
||||
|
||||
# 在Linux系统,你可能还需要运行此命令安装playwright依赖
|
||||
playwright install-deps
|
||||
|
||||
# 首次后会在data目录下生成config.yaml文件
|
||||
# config.yaml用户配置插件
|
||||
```
|
||||
@ -159,6 +155,8 @@ playwright install-deps
|
||||
'
|
||||
# 此处填写你的数据库地址
|
||||
# 示例: "postgres://user:password@127.0.0.1:5432/database"
|
||||
# 示例: "mysql://user:password@127.0.0.1:5432/database"
|
||||
# 示例: "sqlite:data/db/zhenxun.db" 在data目录下建立db文件夹
|
||||
DB_URL = "" # 数据库地址
|
||||
|
||||
|
||||
@ -167,7 +165,7 @@ playwright install-deps
|
||||
|
||||
```
|
||||
|
||||
## 功能列表 (旧版列表)
|
||||
<!-- ## 功能列表 (旧版列表)
|
||||
|
||||
<details>
|
||||
<summary>已实现的功能</summary>
|
||||
@ -176,7 +174,7 @@ playwright install-deps
|
||||
|
||||
- [x] 昵称系统(群与群与私聊分开.)
|
||||
|
||||
- [x] 图灵AI(会把'你'等关键字替换为你的昵称),且带有 [AnimeThesaurus](https://github.com/Kyomotoi/AnimeThesaurus),够味
|
||||
- [x] 图灵 AI(会把'你'等关键字替换为你的昵称),且带有 [AnimeThesaurus](https://github.com/Kyomotoi/AnimeThesaurus),够味
|
||||
- [x] 签到/我的签到/好感度排行/好感度总排行(影响色图概率和开箱次数,支持配置)
|
||||
- [x] 发送某文件夹下的随机图片(支持自定义,默认:美图,萝莉,壁纸)
|
||||
- [x] 色图(这不是基础功能嘛喂)
|
||||
@ -185,12 +183,12 @@ playwright install-deps
|
||||
- [x] 鸡汤/语录
|
||||
- [x] 骂我(钉宫语音)
|
||||
- [x] 戳一戳(概率发送美图,钉宫语音或者戳回去)
|
||||
- [x] 模拟开箱/我的开箱/群开箱统计/我的金色/设置cookie(csgo,内置爬虫脚本,需要提前抓取数据和图片,需要session,可能需要代理,阿里云服务器等ip也许已经被ban了(我无代理访问失败),如果访问太多账号API调用可能被禁止访问api!)
|
||||
- [x] 模拟开箱/我的开箱/群开箱统计/我的金色/设置 cookie(csgo,内置爬虫脚本,需要提前抓取数据和图片,需要 session,可能需要代理,阿里云服务器等 ip 也许已经被 ban 了(我无代理访问失败),如果访问太多账号 API 调用可能被禁止访问 api!)
|
||||
- [x] 鲁迅说过
|
||||
- [x] 构造假消息(自定义的分享链接)
|
||||
- [x] 商店/我的金币/购买道具/使用道具
|
||||
- [x] 8种手游抽卡 (查看 [nonebot_plugin_gamedraw](https://github.com/HibiKier/nonebot_plugin_gamedraw))
|
||||
- [x] 我有一个朋友想问问..(借鉴pcrbot插件)
|
||||
- [x] 8 种手游抽卡 (查看 [nonebot_plugin_gamedraw](https://github.com/HibiKier/nonebot_plugin_gamedraw))
|
||||
- [x] 我有一个朋友想问问..(借鉴 pcrbot 插件)
|
||||
- [x] 原神黄历
|
||||
- [x] 原神今日素材
|
||||
- [x] 原神资源查询 (借鉴[Genshin_Impact_bot](https://github.com/H-K-Y/Genshin_Impact_bot)插件)
|
||||
@ -200,37 +198,37 @@ playwright install-deps
|
||||
- [x] 原神签到/自动签到
|
||||
- [x] 金币红包
|
||||
- [x] 微博热搜
|
||||
- [x] B站主播/UP/番剧订阅
|
||||
- [x] B 站主播/UP/番剧订阅
|
||||
|
||||
- [x] pil对图片的一些操作
|
||||
- [x] BUFF饰品底价查询(需要session)
|
||||
- [x] pil 对图片的一些操作
|
||||
- [x] BUFF 饰品底价查询(需要 session)
|
||||
- [x] 天气查询
|
||||
- [x] 疫情查询
|
||||
- [x] bt磁力搜索(咳咳,这功能我想dddd)
|
||||
- [x] reimu搜索(上车) (使用[XUN_Langskip](https://github.com/Angel-Hair/XUN_Bot)的插件)
|
||||
- [x] bt 磁力搜索(咳咳,这功能我想 dddd)
|
||||
- [x] reimu 搜索(上车) (使用[XUN_Langskip](https://github.com/Angel-Hair/XUN_Bot)的插件)
|
||||
- [x] 靠图识番 (使用[XUN_Langskip](https://github.com/Angel-Hair/XUN_Bot)的插件)
|
||||
- [x] 以图搜图 (使用[nonebot_plugin_picsearcher](https://github.com/synodriver/nonebot_plugin_picsearcher)插件)
|
||||
- [x] 搜番
|
||||
- [x] 点歌 [nonebot_plugin_songpicker2](https://github.com/maxesisn/nonebot_plugin_songpicker2)插件(删除了选歌和评论)
|
||||
- [x] epic免费游戏
|
||||
- [x] p站排行榜
|
||||
- [x] p站搜图
|
||||
- [x] epic 免费游戏
|
||||
- [x] p 站排行榜
|
||||
- [x] p 站搜图
|
||||
- [x] 翻译(日英韩)
|
||||
- [x] pix图库(一个自己的图库,含有增删查改,黑名单等命令)
|
||||
- [x] pix 图库(一个自己的图库,含有增删查改,黑名单等命令)
|
||||
|
||||
- [x] 查看当前群欢迎消息
|
||||
- [x] 查看该群自己的权限
|
||||
- [x] 我的信息(只是为了看看什么时候入群)
|
||||
- [x] 更新信息(如果继续更新的话)
|
||||
- [x] go-cqhttp最新版下载和上传(不需要请删除)
|
||||
- [x] go-cqhttp 最新版下载和上传(不需要请删除)
|
||||
- [x] 撤回
|
||||
- [x] 滴滴滴-(用户对超级用户发送消息)
|
||||
- [x] 金币红包/金币排行
|
||||
- [x] 俄罗斯轮盘/胜场排行/败场排行/欧洲人排行/慈善家排行
|
||||
- [x] 网易云热评
|
||||
- [x] 念首古诗
|
||||
- [x] 获取b站视频封面
|
||||
- [x] 通过PID获取图片
|
||||
- [x] 获取 b 站视频封面
|
||||
- [x] 通过 PID 获取图片
|
||||
- [x] 功能统计可视化
|
||||
- [x] 词云
|
||||
- [x] 关于
|
||||
@ -242,12 +240,12 @@ playwright install-deps
|
||||
- [x] 95%的群功能开关
|
||||
- [x] 查看群内被动技能状态
|
||||
- [x] 自定义群欢迎消息(是真寻的不是管家的!)
|
||||
- [x] .ban/.unban(支持设置ban时长)= 黑白名单
|
||||
- [x] .ban/.unban(支持设置 ban 时长)= 黑白名单
|
||||
- [x] 刷屏禁言相关:刷屏检测设置/设置禁言时长/设置检测次数
|
||||
- [x] 上传图片/连续上传图片 (上传图片至指定图库)
|
||||
- [x] 移动图片 (同上)
|
||||
- [x] 删除图片 (同上)
|
||||
- [x] 群内B站订阅
|
||||
- [x] 群内 B 站订阅
|
||||
- [x] 词条设置
|
||||
- [x] 休息吧/醒来
|
||||
|
||||
@ -267,17 +265,17 @@ playwright install-deps
|
||||
- [x] 修改群权限
|
||||
- [x] ban
|
||||
- [x] 更新色图
|
||||
- [x] 更新价格/更加图片(csgo开箱)
|
||||
- [x] 更新价格/更加图片(csgo 开箱)
|
||||
- [x] 重载原神/方舟/赛马娘/坎公骑冠剑卡池
|
||||
- [x] 更新原神今日素材/更新原神资源信息
|
||||
- [x] PIX相关操作
|
||||
- [x] PIX 相关操作
|
||||
- [x] 检查更新真寻
|
||||
- [x] 重启
|
||||
- [x] 添加/删除/查看群白名单
|
||||
- [x] 功能开关(更多设置)
|
||||
- [x] 功能状态
|
||||
- [x] b了
|
||||
- [x] 执行sql
|
||||
- [x] b 了
|
||||
- [x] 执行 sql
|
||||
- [x] 重载配置
|
||||
- [x] 清理临时数据
|
||||
- [x] 增删群认证
|
||||
@ -296,9 +294,9 @@ playwright install-deps
|
||||
|
||||
- [x] 群早晚安
|
||||
- [x] 每日开箱重置提醒
|
||||
- [x] b站转发解析(解析b站分享信息,支持bv,bilibili链接,b站手机端转发卡片,cv,b23.tv),且5分钟内不解析相同url
|
||||
- [x] b 站转发解析(解析 b 站分享信息,支持 bv,bilibili 链接,b 站手机端转发卡片,cv,b23.tv),且 5 分钟内不解析相同 url
|
||||
- [x] 丢人爬(爬表情包)
|
||||
- [x] epic通知(每日发送epic免费游戏链接)
|
||||
- [x] epic 通知(每日发送 epic 免费游戏链接)
|
||||
- [x] 原神黄历提醒
|
||||
- [x] 复读
|
||||
|
||||
@ -307,15 +305,15 @@ playwright install-deps
|
||||
- [x] 刷屏禁言检测
|
||||
|
||||
- [x] 功能调用统计
|
||||
- [x] 检测恶意触发命令(将被最高权限ban掉30分钟,只有最高权限(9级)可以进行unban)
|
||||
- [x] 检测恶意触发命令(将被最高权限 ban 掉 30 分钟,只有最高权限(9 级)可以进行 unban)
|
||||
- [x] 自动同意好友请求,加群请求将会提醒管理员,退群提示,加群欢迎等等
|
||||
- [x] 群聊时间检测(当群聊最后一人发言时间大于当前36小时后将关闭该群所有通知(即被动技能))
|
||||
- [x] 群聊时间检测(当群聊最后一人发言时间大于当前 36 小时后将关闭该群所有通知(即被动技能))
|
||||
- [x] 群管理员监控,自动为新晋管理员增加权限,为失去群管理员的用户删除权限
|
||||
- [x] 群权限系统
|
||||
- [x] 定时更新权限
|
||||
- [x] 自动配置重载
|
||||
|
||||
</details>
|
||||
</details> -->
|
||||
|
||||
## [爱发电](https://afdian.net/@HibiKier)
|
||||
|
||||
@ -325,7 +323,7 @@ playwright install-deps
|
||||
|
||||
### 感谢名单
|
||||
|
||||
(可以告诉我你的 **github** 地址,我偷偷换掉0v|)
|
||||
(可以告诉我你的 **github** 地址,我偷偷换掉 0v|)
|
||||
|
||||
[shenqi](https://afdian.net/u/fa923a8cfe3d11eba61752540025c377)
|
||||
[A_Kyuu](https://afdian.net/u/b83954fc2c1211eba9eb52540025c377)
|
||||
@ -343,13 +341,13 @@ playwright install-deps
|
||||
[本喵无敌哒](https://afdian.net/u/dffaa9005bc911ebb69b52540025c377)
|
||||
[椎名冬羽](https://afdian.net/u/ca1ebd64395e11ed81b452540025c377)
|
||||
[kaito](https://afdian.net/u/a055e20a498811eab1f052540025c377)
|
||||
[笑柒XIAO_Q7](https://afdian.net/u/4696db5c529111ec84ea52540025c377)
|
||||
[笑柒 XIAO_Q7](https://afdian.net/u/4696db5c529111ec84ea52540025c377)
|
||||
[请问一份爱多少钱](https://afdian.net/u/f57ef6602dbd11ed977f52540025c377)
|
||||
[咸鱼鱼鱼鱼](https://afdian.net/u/8e39b9a400e011ed9f4a52540025c377)
|
||||
[Kafka](https://afdian.net/u/41d66798ef6911ecbc5952540025c377)
|
||||
[墨然](https://afdian.net/u/8aa5874a644d11eb8a6752540025c377)
|
||||
[爱发电用户\_T9e4](https://afdian.net/u/2ad1bb82f3a711eca22852540025c377)
|
||||
[笑柒XIAO_Q7](https://afdian.net/u/4696db5c529111ec84ea52540025c377)
|
||||
[笑柒 XIAO_Q7](https://afdian.net/u/4696db5c529111ec84ea52540025c377)
|
||||
[noahzark](https://afdian.net/a/noahzark)
|
||||
[腊条](https://afdian.net/u/f739c4d69eca11eba94b52540025c377)
|
||||
[ze roller](https://afdian.net/u/0e599e96257211ed805152540025c377)
|
||||
@ -374,11 +372,11 @@ playwright install-deps
|
||||
|
||||
</details>
|
||||
|
||||
## 更新
|
||||
<!-- ## 更新
|
||||
|
||||
### 2024/8/11
|
||||
|
||||
- 更新dev
|
||||
- 更新 dev -->
|
||||
|
||||
<!-- ### 2024/1/25
|
||||
|
||||
@ -820,20 +818,20 @@ playwright install-deps
|
||||
|
||||
## Todo
|
||||
|
||||
- [x] web管理
|
||||
- [x] web 管理
|
||||
|
||||
## 感谢
|
||||
|
||||
[botuniverse / onebot](https://github.com/botuniverse/onebot) :超棒的机器人协议
|
||||
[Mrs4s / go-cqhttp](https://github.com/Mrs4s/go-cqhttp) :cqhttp的golang实现,轻量、原生跨平台.
|
||||
[nonebot / nonebot2](https://github.com/nonebot/nonebot2) :跨平台Python异步机器人框架
|
||||
[Angel-Hair / XUN_Bot](https://github.com/Angel-Hair/XUN_Bot) :一个基于NoneBot和酷Q的功能性QQ机器人
|
||||
[pcrbot / cappuccilo_plugins](https://github.com/pcrbot/cappuccilo_plugins) :hoshino插件合集
|
||||
[Mrs4s / go-cqhttp](https://github.com/Mrs4s/go-cqhttp) :cqhttp 的 golang 实现,轻量、原生跨平台.
|
||||
[nonebot / nonebot2](https://github.com/nonebot/nonebot2) :跨平台 Python 异步机器人框架
|
||||
[Angel-Hair / XUN_Bot](https://github.com/Angel-Hair/XUN_Bot) :一个基于 NoneBot 和酷 Q 的功能性 QQ 机器人
|
||||
[pcrbot / cappuccilo_plugins](https://github.com/pcrbot/cappuccilo_plugins) :hoshino 插件合集
|
||||
[MeetWq /nonebot-plugin-withdraw](https://github.com/MeetWq/nonebot-plugin-withdraw) :A simple withdraw plugin for Nonebot2
|
||||
[maxesisn / nonebot_plugin_songpicker2](https://github.com/maxesisn/nonebot_plugin_songpicker2) :适用于nonebot2的点歌插件
|
||||
[maxesisn / nonebot_plugin_songpicker2](https://github.com/maxesisn/nonebot_plugin_songpicker2) :适用于 nonebot2 的点歌插件
|
||||
[nonepkg / nonebot-plugin-manager](https://github.com/nonepkg/nonebot-plugin-manager) :Nonebot Plugin Manager base on import hook
|
||||
[H-K-Y / Genshin_Impact_bot](https://github.com/H-K-Y/Genshin_Impact_bot) :原神bot,这是一个基于nonebot和HoshinoBot的原神娱乐及信息查询插件
|
||||
[NothAmor / nonebot2_luxun_says](https://github.com/NothAmor/nonebot2_luxun_says) :基于nonebot2机器人框架的鲁迅说插件
|
||||
[Kyomotoi / AnimeThesaurus](https://github.com/Kyomotoi/AnimeThesaurus) :一个~~特二刺螈~~(文爱)的适用于任何bot的词库
|
||||
[Ailitonia / omega-miya](https://github.com/Ailitonia/omega-miya) :基于nonebot2的qq机器人
|
||||
[KimigaiiWuyi / GenshinUID](https://github.com/KimigaiiWuyi/GenshinUID) :一个基于HoshinoBot/NoneBot2的原神UID查询插件
|
||||
[H-K-Y / Genshin_Impact_bot](https://github.com/H-K-Y/Genshin_Impact_bot) :原神 bot,这是一个基于 nonebot 和 HoshinoBot 的原神娱乐及信息查询插件
|
||||
[NothAmor / nonebot2_luxun_says](https://github.com/NothAmor/nonebot2_luxun_says) :基于 nonebot2 机器人框架的鲁迅说插件
|
||||
[Kyomotoi / AnimeThesaurus](https://github.com/Kyomotoi/AnimeThesaurus) :一个~~特二刺螈~~(文爱)的适用于任何 bot 的词库
|
||||
[Ailitonia / omega-miya](https://github.com/Ailitonia/omega-miya) :基于 nonebot2 的 qq 机器人
|
||||
[KimigaiiWuyi / GenshinUID](https://github.com/KimigaiiWuyi/GenshinUID) :一个基于 HoshinoBot/NoneBot2 的原神 UID 查询插件
|
||||
|
||||
@ -1 +1 @@
|
||||
__version__: v0.2.2
|
||||
__version__: v0.2.3
|
||||
|
||||
BIN
docs_image/zhenxun_help.png
Normal file
|
After Width: | Height: | Size: 917 KiB |
333
poetry.lock
generated
@ -1,5 +1,26 @@
|
||||
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "aiocache"
|
||||
version = "0.12.2"
|
||||
description = "multi backend asyncio cache"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "aiocache-0.12.2-py2.py3-none-any.whl", hash = "sha256:9b6fa30634ab0bfc3ecc44928a91ff07c6ea16d27d55469636b296ebc6eb5918"},
|
||||
{file = "aiocache-0.12.2.tar.gz", hash = "sha256:b41c9a145b050a5dcbae1599f847db6dd445193b1f3bd172d8e0fe0cb9e96684"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
memcached = ["aiomcache (>=0.5.2)"]
|
||||
msgpack = ["msgpack (>=0.5.5)"]
|
||||
redis = ["redis (>=4.2.0)"]
|
||||
|
||||
[package.source]
|
||||
type = "legacy"
|
||||
url = "https://mirrors.aliyun.com/pypi/simple"
|
||||
reference = "ali"
|
||||
|
||||
[[package]]
|
||||
name = "aiofiles"
|
||||
version = "23.2.1"
|
||||
@ -249,13 +270,13 @@ reference = "ali"
|
||||
|
||||
[[package]]
|
||||
name = "arclet-alconna"
|
||||
version = "1.8.28"
|
||||
version = "1.8.23"
|
||||
description = "A High-performance, Generality, Humane Command Line Arguments Parser Library."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "arclet_alconna-1.8.28-py3-none-any.whl", hash = "sha256:e1819e063b2f53b94765d93d269e9e7dbf5c39e275f24d7428374a1e7bf0a654"},
|
||||
{file = "arclet_alconna-1.8.28.tar.gz", hash = "sha256:1cc6c0fe3c04d33c63148d3a606f309de6f79e18861f69e01e1e7f068c852ac9"},
|
||||
{file = "arclet_alconna-1.8.23-py3-none-any.whl", hash = "sha256:d4d8a427715408399e46530ec6bdefff4de72ff5d51183fa50ce5ea56a4e2a2a"},
|
||||
{file = "arclet_alconna-1.8.23.tar.gz", hash = "sha256:f811caf60dc4231b70a6885fe1af35aa95ae93bad46566e9086b623f449c9a09"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -2979,6 +3000,22 @@ type = "legacy"
|
||||
url = "https://mirrors.aliyun.com/pypi/simple"
|
||||
reference = "ali"
|
||||
|
||||
[[package]]
|
||||
name = "py-cpuinfo"
|
||||
version = "9.0.0"
|
||||
description = "Get CPU info with pure Python"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690"},
|
||||
{file = "py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5"},
|
||||
]
|
||||
|
||||
[package.source]
|
||||
type = "legacy"
|
||||
url = "https://mirrors.aliyun.com/pypi/simple"
|
||||
reference = "ali"
|
||||
|
||||
[[package]]
|
||||
name = "pyasn1"
|
||||
version = "0.6.0"
|
||||
@ -4040,13 +4077,13 @@ reference = "ali"
|
||||
|
||||
[[package]]
|
||||
name = "starlette"
|
||||
version = "0.38.2"
|
||||
version = "0.38.4"
|
||||
description = "The little ASGI library that shines."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "starlette-0.38.2-py3-none-any.whl", hash = "sha256:4ec6a59df6bbafdab5f567754481657f7ed90dc9d69b0c9ff017907dd54faeff"},
|
||||
{file = "starlette-0.38.2.tar.gz", hash = "sha256:c7c0441065252160993a1a37cf2a73bb64d271b17303e0b0c1eb7191cfb12d75"},
|
||||
{file = "starlette-0.38.4-py3-none-any.whl", hash = "sha256:526f53a77f0e43b85f583438aee1a940fd84f8fd610353e8b0c1a77ad8a87e76"},
|
||||
{file = "starlette-0.38.4.tar.gz", hash = "sha256:53a7439060304a208fea17ed407e998f46da5e5d9b1addfea3040094512a6379"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -4083,58 +4120,58 @@ reference = "ali"
|
||||
|
||||
[[package]]
|
||||
name = "tarina"
|
||||
version = "0.5.7"
|
||||
version = "0.5.8"
|
||||
description = "A collection of common utils for Arclet"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "tarina-0.5.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5961d5f905f5c6dcf2c35f4e3c872cc52624e55a1827c441fae7178619bbe85"},
|
||||
{file = "tarina-0.5.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba2952fe72780b3949c2c5c6cc0f70501861e560eec2bbf7f084d5e592e5189c"},
|
||||
{file = "tarina-0.5.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ceb6afba88d5029e8558898cc579142375bdfef5601309a13b83cbc845bd8761"},
|
||||
{file = "tarina-0.5.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8bdd6d99df7fff93f97dded35c2f5caf8721422d7c055dd97bd2cb5cd27bf32d"},
|
||||
{file = "tarina-0.5.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69a7af7c0b0bce035b9793c9c0dc8e8f612910e4ba1850c709c10a579fce04d6"},
|
||||
{file = "tarina-0.5.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:dcdc77e63fabefaa7a5107f2f46af41b4b3e6981eebfa09d984955c303918815"},
|
||||
{file = "tarina-0.5.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba2cab81c722659f2170f468b0f1f6f1c32b7ea5983bda5f7134b9adfa3431a1"},
|
||||
{file = "tarina-0.5.7-cp310-cp310-win32.whl", hash = "sha256:6fe24a94dcfc442d53fcabcdaae1afed764c3ecb8d2b0cc3f3b0f28b3d8ed888"},
|
||||
{file = "tarina-0.5.7-cp310-cp310-win_amd64.whl", hash = "sha256:331a0fb8fa1d2b64692f1de17a4ccce3ffd63dc130f6f1ce2b2a7226472e2109"},
|
||||
{file = "tarina-0.5.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9f7a639aab35ee3164f051f5ee05c4bf9fda9d3d57886a293b281a3430a10b20"},
|
||||
{file = "tarina-0.5.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9ae9e07d42c3e67bd23cc70aa1c67d5feb306e95a9bd779af491d593fd5dd210"},
|
||||
{file = "tarina-0.5.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0eaa0a850438c7786e88776eb053a95552d7652a28bfd0e69db9406c73ae23ca"},
|
||||
{file = "tarina-0.5.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7986e082702a349558c853f5bae81ca426d02cb93fa91844e3a0c0d0a079c5b9"},
|
||||
{file = "tarina-0.5.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c07c2b9ec4e501163b356276c8eedbd1a1f4d89bf01e06bf314a78eedfd328bf"},
|
||||
{file = "tarina-0.5.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a3b92ba9b7232466a8e6a0372c4530ed9ec58c207c4efb0a8d1e9723423c6c34"},
|
||||
{file = "tarina-0.5.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:40ac0dda54e2065d2b64a171c752e8a00ffd9bc62e320295f6a8f02bdc9cbbf1"},
|
||||
{file = "tarina-0.5.7-cp311-cp311-win32.whl", hash = "sha256:c617fdb74692488e77452c16a55175876691553dbea32967bd5491ee0604d49e"},
|
||||
{file = "tarina-0.5.7-cp311-cp311-win_amd64.whl", hash = "sha256:7d265d0a5707fa6cf5d9adc5796b39ece233278f874a4a8a4408bb13afcb8e8a"},
|
||||
{file = "tarina-0.5.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:45014464bf46a78ab2d0a3ca3fb90f4b5d2acecca94c20b42b43dd875645462e"},
|
||||
{file = "tarina-0.5.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e7f0d76fb06da8f7ad7ffc40575c71e9b0e6395f17a3c4fa615efef2db3b3ca1"},
|
||||
{file = "tarina-0.5.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4035c73ab5e6e8d5efad5b64ea197123368486ba62f75d1e2b23d927deb5e9ef"},
|
||||
{file = "tarina-0.5.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bedb373e9cd09d18c2cdc1b0deec6da3b631792f2438239ade00ba5c05f35aa6"},
|
||||
{file = "tarina-0.5.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6313ea490f5a9de4ce715b3cf4850226b950a69dc7cf29e3e8f632db075992e7"},
|
||||
{file = "tarina-0.5.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b0c920bbd0c683998cbaf2ed8ead3fbd5425a07c1b314a26aa5a803044401f6e"},
|
||||
{file = "tarina-0.5.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:6c791cf298560b268194641fafc34f12f9fb13abaa7e16e726af76ad23786268"},
|
||||
{file = "tarina-0.5.7-cp312-cp312-win32.whl", hash = "sha256:f5f367eb371ca62106650e21691b9abc72e5bba870e29294e9b371e00f307bc4"},
|
||||
{file = "tarina-0.5.7-cp312-cp312-win_amd64.whl", hash = "sha256:f2bef092259d8abadcd509395edb75a8d4495c0c49970e8832f8aea542ac1a89"},
|
||||
{file = "tarina-0.5.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:74b5f3f972818563febb170c4f5847b35997bb005e69ca7c4b60112e08b693a8"},
|
||||
{file = "tarina-0.5.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fda2f3ae7a9b49505bc3444ba3c083ad943bafe260e2f970c568e4b95bd2dd54"},
|
||||
{file = "tarina-0.5.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:65d56a07d8360ada2ee66aadbc0806a140889d7989d30e331c6666d3d6e4d770"},
|
||||
{file = "tarina-0.5.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bef434b0aabe6652e7dbb357df817339d4ef631271cc74334605e86d2f73c89"},
|
||||
{file = "tarina-0.5.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae9d62a0b9dedb0b7636907d1ba8f72e2bc7e8cf7a98502ac1ab3c4c5938fdbf"},
|
||||
{file = "tarina-0.5.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:63a7b76d6ff2306e53e7b1fc109295da725ebac97bfcece4f14710f4d48a6501"},
|
||||
{file = "tarina-0.5.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9695d29303f4aa2a58e13b05d67521e8d80338737be83ca3f0f4677ff21d3aef"},
|
||||
{file = "tarina-0.5.7-cp38-cp38-win32.whl", hash = "sha256:2972db11adc43d2c11b689a1c9f093ef219b856ba2dd3dff37b9310d72758453"},
|
||||
{file = "tarina-0.5.7-cp38-cp38-win_amd64.whl", hash = "sha256:b9bc273bb9b10657305d116b4a2eeed5c8d13594eb1b66609b41c98e30a1dea4"},
|
||||
{file = "tarina-0.5.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b209cb7997a601d2acc5a5ffd3ee6aef59658974b3a9ab695042a3f438b64261"},
|
||||
{file = "tarina-0.5.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db525d8b1ec941c037a54fe9c4e2c39a50ed80c50b45d74422df585a5fbb3492"},
|
||||
{file = "tarina-0.5.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8abcbcbfa462f0938b4b441cf4daa500ca105ef011fa6703d6c5f241ab63cadc"},
|
||||
{file = "tarina-0.5.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e09bbc03ec5e1af1972ad814d1141f03ceae101154591bcf9bc5497eaec1cf41"},
|
||||
{file = "tarina-0.5.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:417f084cfd111791ee1cfe84c9d8788ef83643890109e21dff33765126645f5e"},
|
||||
{file = "tarina-0.5.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:62ca5b8e6f22c39964fc4753b0008e50eba56349912485c7c81e67b181ed490c"},
|
||||
{file = "tarina-0.5.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:dac0eecff80cb6811fd88bae7051c52700d9b01b04e0e178a6a5beafceaba160"},
|
||||
{file = "tarina-0.5.7-cp39-cp39-win32.whl", hash = "sha256:7381df78770e765aa68b5fd776dc92b3903e029c46cd32ed26b5101625784805"},
|
||||
{file = "tarina-0.5.7-cp39-cp39-win_amd64.whl", hash = "sha256:002583f127d0f5be04d9e2e078dbb0023920c549cf184bc14aa5072ec2f54f15"},
|
||||
{file = "tarina-0.5.7-py3-none-any.whl", hash = "sha256:358af5b4e1cf2a5beb0ba8deeb75675e01025ec899a841e8fb0395a9bebd37c5"},
|
||||
{file = "tarina-0.5.7.tar.gz", hash = "sha256:7e9f39405bda0a933e6880665ab55a9cf251f405ca691ad738b65398c15f4ff5"},
|
||||
{file = "tarina-0.5.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:76512f0868f0d24684888c173f1eb8ad301fa419920168f4072f9f0e2e903fec"},
|
||||
{file = "tarina-0.5.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2ffc4dd5977c7f444e6352b881656262033cd23c7bb79ff86dce0cab557fb1c2"},
|
||||
{file = "tarina-0.5.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bc30f6e6a8a078c6fde61689b8db7e6146f7116daacce6b1dbb247647c0859d9"},
|
||||
{file = "tarina-0.5.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46ea40c1a19ddc7f034f1c07a5daae120295b38639fe12eb27973b99602ef699"},
|
||||
{file = "tarina-0.5.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c23dfa1cbccafe333eb666e97f1887325c78a134601a2df72593bfb6a3541255"},
|
||||
{file = "tarina-0.5.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7be68f9155f641fb74e6318f6ee85ab86cacb2a3c53424f168fbd0b9e0468e33"},
|
||||
{file = "tarina-0.5.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6863c679ba9af3059f9501b038559e1c07b969e81894e9259c1bbfc385545c26"},
|
||||
{file = "tarina-0.5.8-cp310-cp310-win32.whl", hash = "sha256:2024ca41524d17b6d09b6a12fa33e35413126001b566bdfed61e514a70ec4d44"},
|
||||
{file = "tarina-0.5.8-cp310-cp310-win_amd64.whl", hash = "sha256:f061179a48d71206af5ed7161550b7d72724f5ea24904a3ffcbf748aa047868c"},
|
||||
{file = "tarina-0.5.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9b730d605691c1afc074f684b77c12e921d8a0a278b80b5fc016ab2bf75ee081"},
|
||||
{file = "tarina-0.5.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:21dfdacf4ca5b46ecfbcd2ea92445abf9aced634aaef285fec8d914163261db8"},
|
||||
{file = "tarina-0.5.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b3162eace1e5193313f1523a943b5ae14464199782f235e87702da9ee3fb37a6"},
|
||||
{file = "tarina-0.5.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:385882a2991046aa05f7b183f386ec2c949076aeacb4acad525ead63342d73f7"},
|
||||
{file = "tarina-0.5.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76ee0f135cbe26549592fa12691cb057aa4464d4182c35d7d967361eba52ed95"},
|
||||
{file = "tarina-0.5.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2c188c34143ae6bdcee13bac089845f1ca7d32169d85f172091550e0f34fda35"},
|
||||
{file = "tarina-0.5.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a45e5f0fccd0267a15582b9d8cfa4b21fca5c1c690ced673f0f58869b98cb178"},
|
||||
{file = "tarina-0.5.8-cp311-cp311-win32.whl", hash = "sha256:e554bd8e22a43ffc8f441d771585e81f90150de2f9e9d9a984c7b004bb613c10"},
|
||||
{file = "tarina-0.5.8-cp311-cp311-win_amd64.whl", hash = "sha256:51c8b7ad1cc114efde36ab09687b5f93afde27ad082cd38721dc327c7f0d922d"},
|
||||
{file = "tarina-0.5.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c95f227e7265cfce8c4fb5eebef2a148934b52b782527ded278a4e0926b90ceb"},
|
||||
{file = "tarina-0.5.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a394bd75c92d39c0e4c1ee40404de24316f4263f10e296e8d4e19bd0a3c50e55"},
|
||||
{file = "tarina-0.5.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9db70e6fb97ee8a87da52e9ced52ee6df7c468f75b72ef98af5a97929e12bc2d"},
|
||||
{file = "tarina-0.5.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b713717dcafcd03a86f41509b6c9ebc2749419c9c8c6d559edd6fdfaca6f354"},
|
||||
{file = "tarina-0.5.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ccaf87a54e062a2d72a60d699198760684aca231c7de7de11d61c191d1e870bf"},
|
||||
{file = "tarina-0.5.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a1dc7e8e84ab4e0d6bfb3e4e9c82c7d8a4c002794b7b44010658f0f81e8b5e52"},
|
||||
{file = "tarina-0.5.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:dbc6e78e3ee9b24f9c0feb2c14c17d9696098abf6530ae63d6f4158ab7038c38"},
|
||||
{file = "tarina-0.5.8-cp312-cp312-win32.whl", hash = "sha256:4e1a08f1c3d40f935cc8c9507b7ea669b002a53dc7334c9b0ede9f71cf9d1cba"},
|
||||
{file = "tarina-0.5.8-cp312-cp312-win_amd64.whl", hash = "sha256:ab90fd830ec05d5f7cd001906fdd1a3e00d8c9fd221772d02bb87a7aec947925"},
|
||||
{file = "tarina-0.5.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f5df6b179284bd5b1d609d97f6b941a1928ab29fbcd364d183a49558a74a7b1c"},
|
||||
{file = "tarina-0.5.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a88f45116b8b76ad50b4cdaf350730cdf35edee7a4ebe1c6373b460f202965ae"},
|
||||
{file = "tarina-0.5.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e80b99cd0c43c0c8b8b99c8348a5970721eca60198032b041af3efe8f661f3c3"},
|
||||
{file = "tarina-0.5.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99193e0b51c7220f2b3edb06102a37b8c76bb5f1ce0c9bcfba7020d907e72cca"},
|
||||
{file = "tarina-0.5.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47811cfabd57f24da6825b3b65fd0d7417d2950474782bde5c003c3ad2847d80"},
|
||||
{file = "tarina-0.5.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a36874609c532e52e3b71f64b1d35efe38d6ea7a43d96dba64d1e4c036203430"},
|
||||
{file = "tarina-0.5.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9734c9ed62fa6eb62ea7e8f5c32057eda6ca1405e63a12d1951d15bf9ee453e1"},
|
||||
{file = "tarina-0.5.8-cp38-cp38-win32.whl", hash = "sha256:2c1391003564baaad6c8ecf847e64d66c0521c871d87cad2a83a90540ba05f3c"},
|
||||
{file = "tarina-0.5.8-cp38-cp38-win_amd64.whl", hash = "sha256:c81e3ccff2e89f93b26b76df5d73c5a79c82456b89fc4054ad7482549dea940a"},
|
||||
{file = "tarina-0.5.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7130939147f54f08eda3c6e0eb4cf8c20a4dfa079de9c9e5a3db7a3f3663674c"},
|
||||
{file = "tarina-0.5.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0763b338533c7bdfca688219a80c905216c7d5e9c854fd1e299f92ae66ed5659"},
|
||||
{file = "tarina-0.5.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a35a155318588dd936348c8bd72618069d2a8bb268d74f070be368fc2b068190"},
|
||||
{file = "tarina-0.5.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05c7ecbf79cf511f8ca13a564d0357ed7cc0cb28260d71dbf4bce29fa1dea779"},
|
||||
{file = "tarina-0.5.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a73271adef1944cbbadaac4e36a979ffa4c531cee8043b31e7777262482ede0c"},
|
||||
{file = "tarina-0.5.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2ae9d864fa5644eeb76e56b79af7727d8c970fd99ed03c77be7afbb1e64e2ba4"},
|
||||
{file = "tarina-0.5.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5efa1fe62b0f0cb3021051fe63b7ecc41c83a3351fb9022f7f450227d27dd04"},
|
||||
{file = "tarina-0.5.8-cp39-cp39-win32.whl", hash = "sha256:d986d11e2b1dd8b2bfe96b4327700db9275c4f2b32ba83cc682b0737d0b79913"},
|
||||
{file = "tarina-0.5.8-cp39-cp39-win_amd64.whl", hash = "sha256:d89b6ee7ee51fc2b1ac3763f06718859e065951e4a995541f9380f7606e5d3db"},
|
||||
{file = "tarina-0.5.8-py3-none-any.whl", hash = "sha256:90740760e9f516677962eff5242a722c616939b123c566a85d7e009ec9868eb3"},
|
||||
{file = "tarina-0.5.8.tar.gz", hash = "sha256:ab5a8b901829242c64a8a0436c7753e894ccae36891ca20a9deda9de6210a0b3"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -4753,101 +4790,103 @@ reference = "ali"
|
||||
|
||||
[[package]]
|
||||
name = "yarl"
|
||||
version = "1.9.4"
|
||||
version = "1.9.7"
|
||||
description = "Yet another URL library"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"},
|
||||
{file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"},
|
||||
{file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"},
|
||||
{file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"},
|
||||
{file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"},
|
||||
{file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"},
|
||||
{file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"},
|
||||
{file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"},
|
||||
{file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"},
|
||||
{file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"},
|
||||
{file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"},
|
||||
{file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"},
|
||||
{file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"},
|
||||
{file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"},
|
||||
{file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"},
|
||||
{file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"},
|
||||
{file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"},
|
||||
{file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"},
|
||||
{file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"},
|
||||
{file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"},
|
||||
{file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:60c04415b31a1611ef5989a6084dd6f6b95652c6a18378b58985667b65b2ecb6"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1787dcfdbe730207acb454548a6e19f80ae75e6d2d1f531c5a777bc1ab6f7952"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f5ddad20363f9f1bbedc95789c897da62f939e6bc855793c3060ef8b9f9407bf"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdb156a06208fc9645ae7cc0fca45c40dd40d7a8c4db626e542525489ca81a9"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:522fa3d300d898402ae4e0fa7c2c21311248ca43827dc362a667de87fdb4f1be"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7f9cabfb8b980791b97a3ae3eab2e38b2ba5eab1af9b7495bdc44e1ce7c89e3"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fc728857df4087da6544fc68f62d7017fa68d74201d5b878e18ed4822c31fb3"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3dba2ebac677184d56374fa3e452b461f5d6a03aa132745e648ae8859361eb6b"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a95167ae34667c5cc7d9206c024f793e8ffbadfb307d5c059de470345de58a21"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9d319ac113ca47352319cbea92d1925a37cb7bd61a8c2f3e3cd2e96eb33cccae"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:2d71a5d818d82586ac46265ae01466e0bda0638760f18b21f1174e0dd58a9d2f"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ff03f1c1ac474c66d474929ae7e4dd195592c1c7cc8c36418528ed81b1ca0a79"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:78250f635f221dde97d02c57aade3313310469bc291888dfe32acd1012594441"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-win32.whl", hash = "sha256:f3aaf9fa960d55bd7876d55d7ea3cc046f3660df1ff73fc1b8c520a741ed1f21"},
|
||||
{file = "yarl-1.9.7-cp310-cp310-win_amd64.whl", hash = "sha256:e8362c941e07fbcde851597672a5e41b21dc292b7d5a1dc439b7a93c9a1af5d9"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:596069ddeaf72b5eb36cd714dcd2b5751d0090d05a8d65113b582ed9e1c801fb"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cb870907e8b86b2f32541403da9455afc1e535ce483e579bea0e6e79a0cc751c"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ca5e86be84492fa403c4dcd4dcaf8e1b1c4ffc747b5176f7c3d09878c45719b0"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a99cecfb51c84d00132db909e83ae388793ca86e48df7ae57f1be0beab0dcce5"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:25508739e9b44d251172145f54c084b71747b09e4d237dc2abb045f46c36a66e"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:60f3b5aec3146b6992640592856414870f5b20eb688c1f1d5f7ac010a7f86561"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1557456afce5db3d655b5f8a31cdcaae1f47e57958760525c44b76e812b4987"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71bb1435a84688ed831220c5305d96161beb65cac4a966374475348aa3de4575"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f87d8645a7a806ec8f66aac5e3b1dcb5014849ff53ffe2a1f0b86ca813f534c7"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:58e3f01673873b8573da3abe138debc63e4e68541b2104a55df4c10c129513a4"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8af0bbd4d84f8abdd9b11be9488e32c76b1501889b73c9e2292a15fb925b378b"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7fc441408ed0d9c6d2d627a02e281c21f5de43eb5209c16636a17fc704f7d0f8"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a9552367dc440870556da47bb289a806f08ad06fbc4054072d193d9e5dd619ba"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-win32.whl", hash = "sha256:628619008680a11d07243391271b46f07f13b75deb9fe92ef342305058c70722"},
|
||||
{file = "yarl-1.9.7-cp311-cp311-win_amd64.whl", hash = "sha256:bc23d870864971c8455cfba17498ccefa53a5719ea9f5fce5e7e9c1606b5755f"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d8cf3d0b67996edc11957aece3fbce4c224d0451c7c3d6154ec3a35d0e55f6b"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3a7748cd66fef49c877e59503e0cc76179caf1158d1080228e67e1db14554f08"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a6fa3aeca8efabb0fbbb3b15e0956b0cb77f7d9db67c107503c30af07cd9e00"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf37dd0008e5ac5c3880198976063c491b6a15b288d150d12833248cf2003acb"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87aa5308482f248f8c3bd9311cd6c7dfd98ea1a8e57e35fb11e4adcac3066003"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:867b13c1b361f9ba5d2f84dc5408082f5d744c83f66de45edc2b96793a9c5e48"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48ce93947554c2c85fe97fc4866646ec90840bc1162e4db349b37d692a811755"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcd3d94b848cba132f39a5b40d80b0847d001a91a6f35a2204505cdd46afe1b2"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d06d6a8f98dd87646d98f0c468be14b201e47ec6092ad569adf835810ad0dffb"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:91567ff4fce73d2e7ac67ed5983ad26ba2343bc28cb22e1e1184a9677df98d7c"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1d5594512541e63188fea640b7f066c218d2176203d6e6f82abf702ae3dca3b2"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9c2743e43183e4afbb07d5605693299b8756baff0b086c25236c761feb0e3c56"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:daa69a3a2204355af39f4cfe7f3870d87c53d77a597b5100b97e3faa9460428b"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-win32.whl", hash = "sha256:36b16884336c15adf79a4bf1d592e0c1ffdb036a760e36a1361565b66785ec6c"},
|
||||
{file = "yarl-1.9.7-cp312-cp312-win_amd64.whl", hash = "sha256:2ead2f87a1174963cc406d18ac93d731fbb190633d3995fa052d10cefae69ed8"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:808eddabcb6f7b2cdb6929b3e021ac824a2c07dc7bc83f7618e18438b1b65781"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:395ab0d8ce6d104a988da429bcbfd445e03fb4c911148dfd523f69d13f772e47"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:49827dfccbd59c4499605c13805e947349295466e490860a855b7c7e82ec9c75"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6b8bbdd425d0978311520ea99fb6c0e9e04e64aee84fac05f3157ace9f81b05"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71d33fd1c219b5b28ee98cd76da0c9398a4ed4792fd75c94135237db05ba5ca8"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62440431741d0b7d410e5cbad800885e3289048140a43390ecab4f0b96dde3bb"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4db97210433366dfba55590e48285b89ad0146c52bf248dd0da492dd9f0f72cf"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:653597b615809f2e5f4dba6cd805608b6fd3597128361a22cc612cf7c7a4d1bf"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df47612129e66f7ce7c9994d4cd4e6852f6e3bf97699375d86991481796eeec8"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5e338b6febbae6c9fe86924bac3ea9c1944e33255c249543cd82a4af6df6047b"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e649d37d04665dddb90994bbf0034331b6c14144cc6f3fbce400dc5f28dc05b7"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0a1b8fd849567be56342e988e72c9d28bd3c77b9296c38b9b42d2fe4813c9d3f"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f9d715b2175dff9a49c6dafdc2ab3f04850ba2f3d4a77f69a5a1786b057a9d45"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-win32.whl", hash = "sha256:bc9233638b07c2e4a3a14bef70f53983389bffa9e8cb90a2da3f67ac9c5e1842"},
|
||||
{file = "yarl-1.9.7-cp313-cp313-win_amd64.whl", hash = "sha256:62e110772330d7116f91e79cd83fef92545cb2f36414c95881477aa01971f75f"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a564155cc2194ecd9c0d8f8dc57059b822a507de5f08120063675eb9540576aa"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:03e917cc44a01e1be60a83ee1a17550b929490aaa5df2a109adc02137bddf06b"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:eefda67ba0ba44ab781e34843c266a76f718772b348f7c5d798d8ea55b95517f"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:316c82b499b6df41444db5dea26ee23ece9356e38cea43a8b2af9e6d8a3558e4"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10452727843bc847596b75e30a7fe92d91829f60747301d1bd60363366776b0b"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:050f3e4d886be55728fef268587d061c5ce6f79a82baba71840801b63441c301"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0aabe557446aa615693a82b4d3803c102fd0e7a6a503bf93d744d182a510184"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23404842228e6fa8ace235024519df37f3f8e173620407644d40ddca571ff0f4"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:34736fcc9d6d7080ebbeb0998ecb91e4f14ad8f18648cf0b3099e2420a225d86"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:48f7a158f3ca67509d21cb02a96964e4798b6f133691cc0c86cf36e26e26ec8f"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:6639444d161c693cdabb073baaed1945c717d3982ecedf23a219bc55a242e728"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:1cd450e10cb53d63962757c3f6f7870be49a3e448c46621d6bd46f8088d532de"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74d3ef5e81f81507cea04bf5ae22f18ef538607a7c754aac2b6e3029956a2842"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-win32.whl", hash = "sha256:4052dbd0c900bece330e3071c636f99dff06e4628461a29b38c6e222a427cf98"},
|
||||
{file = "yarl-1.9.7-cp38-cp38-win_amd64.whl", hash = "sha256:dd08da4f2d171e19bd02083c921f1bef89f8f5f87000d0ffc49aa257bc5a9802"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7ab906a956d2109c6ea11e24c66592b06336e2743509290117f0f7f47d2c1dd3"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d8ad761493d5aaa7ab2a09736e62b8a220cb0b10ff8ccf6968c861cd8718b915"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d35f9cdab0ec5e20cf6d2bd46456cf599052cf49a1698ef06b9592238d1cf1b1"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a48d2b9f0ae29a456fb766ae461691378ecc6cf159dd9f938507d925607591c3"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cf85599c9336b89b92c313519bcaa223d92fa5d98feb4935a47cce2e8722b4b8"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8e8916b1ff7680b1f2b1608c82dc15c569b9f2cb2da100c747c291f1acf18a14"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29c80890e0a64fb0e5f71350d48da330995073881f8b8e623154aef631febfb0"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9163d21aa40ff8528db2aee2b0b6752efe098055b41ab8e5422b2098457199fe"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:65e3098969baf221bb45e3b2f60735fc2b154fc95902131ebc604bae4c629ea6"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cddebd096effe4be90fd378e4224cd575ac99e1c521598a6900e94959006e02e"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8525f955a2dcc281573b6aadeb8ab9c37e2d3428b64ca6a2feec2a794a69c1da"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:5d585c7d834c13f24c7e3e0efaf1a4b7678866940802e11bd6c4d1f99c935e6b"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:78805148e780a9ca66f3123e04741e344b66cf06b4fb13223e3a209f39a6da55"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-win32.whl", hash = "sha256:3f53df493ec80b76969d6e1ae6e4411a55ab1360e02b80c84bd4b33d61a567ba"},
|
||||
{file = "yarl-1.9.7-cp39-cp39-win_amd64.whl", hash = "sha256:c81c28221a85add23a0922a6aeb2cdda7f9723e03e2dfae06fee5c57fe684262"},
|
||||
{file = "yarl-1.9.7-py3-none-any.whl", hash = "sha256:49935cc51d272264358962d050d726c3e5603a616f53e52ea88e9df1728aa2ee"},
|
||||
{file = "yarl-1.9.7.tar.gz", hash = "sha256:f28e602edeeec01fc96daf7728e8052bc2e12a672e2a138561a1ebaf30fd9df7"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -4886,4 +4925,4 @@ reference = "ali"
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "37b5f52dbecdbc89311de46a2c22b634f4fcd2a2babf0b2100e5d4858b15da74"
|
||||
content-hash = "e66133515a2b17715ddf5f887ec31f128751acda1ea67736e9d27b29a9b16b65"
|
||||
|
||||
@ -48,6 +48,9 @@ bilireq = "0.2.3post0"
|
||||
python-jose = { extras = ["cryptography"], version = "^3.3.0" }
|
||||
python-multipart = "^0.0.9"
|
||||
nonebot-plugin-alconna = "0.51.1"
|
||||
arclet-alconna = "1.8.23"
|
||||
aiocache = "^0.12.2"
|
||||
py-cpuinfo = "^9.0.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
nonebug = "^0.3.2"
|
||||
@ -134,6 +137,9 @@ typeCheckingMode = "standard"
|
||||
reportShadowedImports = false
|
||||
disableBytesTypePromotions = true
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
asyncio_mode = "auto"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
BIN
requirements.txt
|
Before Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 245 KiB |
|
Before Width: | Height: | Size: 456 KiB |
|
Before Width: | Height: | Size: 239 KiB |
|
Before Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 160 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 27 KiB |
@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>ECharts Example</title>
|
||||
@ -7,14 +8,15 @@
|
||||
<script src="https://cdn.bootcss.com/echarts/4.2.1/echarts.min.js"></script>
|
||||
<link rel="stylesheet" href="main.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- 图表容器 -->
|
||||
<div id="main" style="width: 1000px;height:500px;"></div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
// 基于准备好的dom,初始化echarts实例
|
||||
var myChart = echarts.init(document.getElementById('main'));
|
||||
|
||||
|
||||
// 指定图表的配置项和数据
|
||||
var option = {
|
||||
xAxis: {
|
||||
@ -23,28 +25,35 @@
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
data: {{data.category_data|tojson}}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: {{data.data|tojson}},
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
// 为每个柱子设置随机颜色
|
||||
color: function () {
|
||||
// 生成一个随机颜色
|
||||
return 'rgb(' +
|
||||
Math.round(Math.random() * 255) + ',' +
|
||||
Math.round(Math.random() * 255) + ',' +
|
||||
Math.round(Math.random() * 255) + ')';
|
||||
}
|
||||
}
|
||||
data: {
|
||||
{
|
||||
data.category_data | tojson
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
},
|
||||
series: [{
|
||||
data: {
|
||||
{
|
||||
data.data | tojson
|
||||
}
|
||||
},
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
// 为每个柱子设置随机颜色
|
||||
color: function () {
|
||||
// 生成一个随机颜色
|
||||
return 'rgb(' +
|
||||
Math.round(Math.random() * 255) + ',' +
|
||||
Math.round(Math.random() * 255) + ',' +
|
||||
Math.round(Math.random() * 255) + ')';
|
||||
}
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
// 使用刚指定的配置项和数据显示图表。
|
||||
myChart.setOption(option);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
182
resources/template/check/main.css
Normal file
@ -0,0 +1,182 @@
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: fzrzFont;
|
||||
/* 导入的字体文件 */
|
||||
src: url("../../font/fzrzExtraBold.ttf");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
body {
|
||||
position: absolute;
|
||||
left: -8px;
|
||||
top: -8px;
|
||||
}
|
||||
|
||||
.wrapper{
|
||||
height: 750px;
|
||||
width: 395px;
|
||||
background-color: antiquewhite;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.top-image {
|
||||
height: 215px;
|
||||
width: 395px;
|
||||
}
|
||||
|
||||
.abs-image {
|
||||
height: 426px;
|
||||
width: 93px;
|
||||
position: absolute;
|
||||
right: 39px;
|
||||
top: 240px;
|
||||
}
|
||||
|
||||
.bot-text {
|
||||
height: 55px;
|
||||
width: 335px;
|
||||
position: relative;
|
||||
padding: 0 30px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.main {
|
||||
height: 448px;
|
||||
width: 335px;
|
||||
padding: 0 30px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.title {
|
||||
background-color: #EB869D;
|
||||
height: 32px;
|
||||
font-family: 'fzrzFont';
|
||||
color: white;
|
||||
width: max-content;
|
||||
border-radius: 20px;
|
||||
padding: 0 10px;
|
||||
float: left;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.title-n {
|
||||
height: 23px;
|
||||
width: 23px;
|
||||
border-radius: 50%;
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
left: 36px;
|
||||
top: 15px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.title-a {
|
||||
background-color: #ED859E;
|
||||
height: 19px;
|
||||
width: 19px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.network {
|
||||
display: flex;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.network-item {
|
||||
font-family: 'fzrzFont';
|
||||
color: #EC859F;
|
||||
display: flex;
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.network-status {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
border-radius: 50%;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.network-text {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.network-item {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.data-status-item {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.data-status {
|
||||
width: 100%;
|
||||
height: 240px;
|
||||
/* background-color:blueviolet; */
|
||||
margin-top: 22px;
|
||||
}
|
||||
|
||||
.data-status-item {
|
||||
display: flex;
|
||||
font-family: 'fzrzFont';
|
||||
font-size: 15px;
|
||||
line-height: 18.5px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.process {
|
||||
height: 28px;
|
||||
width: 105px;
|
||||
border: #ED859E 4px solid;
|
||||
border-radius: 30px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.process-bar {
|
||||
height: 28px;
|
||||
width: 30px;
|
||||
background-color: #EB869D;
|
||||
border-top-right-radius: 30px;
|
||||
border-bottom-right-radius: 30px;
|
||||
}
|
||||
|
||||
.data-status-item-text {
|
||||
margin-left: 10px;
|
||||
color: #EC839D;
|
||||
}
|
||||
|
||||
.line {
|
||||
background-color: #EC859F;
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-family: 'fzrzFont';
|
||||
color: #EC859F;
|
||||
height: 185px;
|
||||
}
|
||||
|
||||
.status-text-title {
|
||||
/* height: 25%; */
|
||||
display: flex;
|
||||
/* justify-content: center; */
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-family: 'fzrzFont';
|
||||
color: #ecbac7;
|
||||
font-size: 10px;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
bottom: 1px;
|
||||
}
|
||||
87
resources/template/check/main.html
Normal file
@ -0,0 +1,87 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>test</title>
|
||||
<!-- <link rel="stylesheet" href="./res/font-awesome/css/font-awesome.min.css"> -->
|
||||
<link rel="stylesheet" href="main.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<img class="top-image" src="res/img/top.jpg"></img>
|
||||
<img class="abs-image" src="res/img/bk.png"></img>
|
||||
<div class="bot-text">
|
||||
<div class="title">
|
||||
<div class="title-n">
|
||||
<div class="title-a"></div>
|
||||
</div>
|
||||
<span style="margin-left: 22px;">{{data.nickname}}自检</span>
|
||||
</div>
|
||||
<div class="network">
|
||||
<div class="network-item">BaiDu<span class="network-status"
|
||||
style="background-color: {{data.baidu}}; border: 1px solid {{data.baidu}}"></span></div>
|
||||
<div class="network-item">Google<span class="network-status"
|
||||
style="background-color: {{data.google}}; border: 1px solid {{data.google}}"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="main">
|
||||
<div class="data-status">
|
||||
<div class="data-status-item">
|
||||
<div class="process">
|
||||
<div class="process-bar" style="width: {{data.cpu_process}}%;"></div>
|
||||
</div>
|
||||
<div class="data-status-item-text">
|
||||
<div>CPU</div>
|
||||
<!-- <div style="font-size: 13px;">0.8% - 3.5Ghz [14core]</div> -->
|
||||
<div style="font-size: 13px;">{{data.cpu_info}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="data-status-item">
|
||||
<div class="process">
|
||||
<div class="process-bar" style="width: {{data.ram_process}}%;"></div>
|
||||
</div>
|
||||
<div class="data-status-item-text">
|
||||
<div>RAM</div>
|
||||
<div>{{data.ram_info}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="data-status-item">
|
||||
<div class="process">
|
||||
<div class="process-bar" style="width: {{data.swap_process}}%;"></div>
|
||||
</div>
|
||||
<div class="data-status-item-text">
|
||||
<div>SWAP</div>
|
||||
<div>{{data.swap_info}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="data-status-item">
|
||||
<div class="process">
|
||||
<div class="process-bar" style="width: {{data.disk_process}}%;"></div>
|
||||
</div>
|
||||
<div class="data-status-item-text">
|
||||
<div>DISK</div>
|
||||
<div>{{data.disk_info}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<div class="status-text">
|
||||
<p class="status-text-title">CPU <span
|
||||
style="font-size: 12px;line-height: 18.5px;">{{data.brand_raw}}</span></p>
|
||||
<p class="status-text-title">SYSTEM <span
|
||||
style="font-size: 13px;line-height: 18.5px;">{{data.system}}</span></p>
|
||||
<p class="status-text-title">VERSION <span>{{data.version}}</span></p>
|
||||
<p class="status-text-title">PLUGINS <span>{{data.plugin_count}} loaded</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tip">Create By Zhenxun</div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="text/javascript" src="main.js">
|
||||
</script>
|
||||
|
||||
</html>
|
||||
0
resources/template/check/main.js
Normal file
BIN
resources/template/check/res/img/bk.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
resources/template/check/res/img/top.jpg
Normal file
|
After Width: | Height: | Size: 209 KiB |
100
resources/template/help/main.css
Normal file
@ -0,0 +1,100 @@
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: fzrzFont;
|
||||
/* 导入的字体文件 */
|
||||
src: url("../../font/fzrzExtraBold.ttf");
|
||||
}
|
||||
|
||||
body {
|
||||
position: absolute;
|
||||
left: -8px;
|
||||
top: -8px;
|
||||
}
|
||||
|
||||
.wrapper{
|
||||
width: 1400px;
|
||||
position: relative;
|
||||
background-image: url('res/img/bk.jpg');
|
||||
background-size: cover;
|
||||
font-family: 'cr105Font';
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
|
||||
.title {
|
||||
font-size: 60px;
|
||||
font-family: 'fzrzFont';
|
||||
/* margin-left: 40px; */
|
||||
/* color: #F67186; */
|
||||
background: linear-gradient(to right, #F67186, #F7889C);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.main {
|
||||
background-image: url('res/img/main.png');
|
||||
background-size: 100% 100%;
|
||||
/* background-size: cover; */
|
||||
height: 100%;
|
||||
width: 1370px;
|
||||
position: relative;
|
||||
padding: 20px;
|
||||
/* box-shadow: 5px 5px 10px 0 rgba(0,0,0,0.5); */
|
||||
}
|
||||
|
||||
.items-border {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding-left: 18px;
|
||||
}
|
||||
|
||||
.items {
|
||||
border: #F67186 2px solid;
|
||||
border-radius: 20px;
|
||||
width: 675px;
|
||||
padding: 30px;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
background-image: url('res/img/title.png');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
height: 55px;
|
||||
width: 350px;
|
||||
font-family: 'fzrzFont';
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: white;
|
||||
font-size: 35px;
|
||||
border-radius: 16px;
|
||||
letter-spacing:4px;
|
||||
}
|
||||
|
||||
.usage-title {
|
||||
font-size: 30px;
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
}
|
||||
|
||||
.item-des {
|
||||
color: #F78094;
|
||||
border-radius: 20px;
|
||||
font-family: 'fzrzFont';
|
||||
font-size: 30px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.item-usage {
|
||||
color: #F78094;
|
||||
border-radius: 20px;
|
||||
font-family: 'fzrzFont';
|
||||
font-size: 20px;
|
||||
border: #F67186 5px dotted;
|
||||
padding: 60px 10px 10px 10px;
|
||||
position: relative;
|
||||
}
|
||||
62
resources/template/help/main.html
Normal file
@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>test</title>
|
||||
<!-- <link rel="stylesheet" href="./res/font-awesome/css/font-awesome.min.css"> -->
|
||||
<link rel="stylesheet" href="main.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<div class="main">
|
||||
<div class="title">
|
||||
{{data.nickname}}的{{data.help_name}}帮助
|
||||
</div>
|
||||
<div class="items-border">
|
||||
{% for plugin in data['plugin_list'] %}
|
||||
<div class="items">
|
||||
<div class="item-title">
|
||||
{{plugin.name}}
|
||||
</div>
|
||||
<div class="item-des">
|
||||
简介: {{plugin.description}}
|
||||
</div>
|
||||
<div class="item-usage">
|
||||
<p class="usage-title">用法:</p>
|
||||
{{plugin.usage}}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- <div class="items">
|
||||
<div class="item-title">
|
||||
刷屏禁言
|
||||
</div>
|
||||
<div class="item-des">
|
||||
简介: 刷屏禁言相关操作
|
||||
</div>
|
||||
<div class="item-usage">
|
||||
用法:<br>
|
||||
指令:<br>
|
||||
设置刷屏: 查看当前设置<br>
|
||||
-c [count]: 检测最大次数<br>
|
||||
-t [time]: 规定时间内<br>
|
||||
-d [duration]: 禁言时长<br>
|
||||
示例:<br>
|
||||
设置刷屏 -c 10: 设置最大次数为10<br>
|
||||
设置刷屏 -t 100 -d 20: 设置规定时间和禁言时长<br>
|
||||
设置刷屏 -d 10: 设置禁言时长为10<br>
|
||||
* 即 X 秒内发送同样消息 N 次,禁言 M 分钟 *
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="text/javascript" src="main.js">
|
||||
</script>
|
||||
|
||||
</html>
|
||||
0
resources/template/help/main.js
Normal file
BIN
resources/template/help/res/img/bk.jpg
Normal file
|
After Width: | Height: | Size: 706 KiB |
BIN
resources/template/help/res/img/main.png
Normal file
|
After Width: | Height: | Size: 78 KiB |
BIN
resources/template/help/res/img/title.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
235
resources/template/my_info/main.css
Normal file
@ -0,0 +1,235 @@
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: fzrzFont;
|
||||
/* 导入的字体文件 */
|
||||
src: url("../../font/HYWenHei-85W.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: systFont;
|
||||
/* 导入的字体文件 */
|
||||
src: url("../../font/syst.otf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: syhtFont;
|
||||
/* 导入的字体文件 */
|
||||
src: url("../../font/syht.otf");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
body {
|
||||
position: absolute;
|
||||
left: -8px;
|
||||
top: -8px;
|
||||
}
|
||||
|
||||
.wrapper{
|
||||
width: 1754px;
|
||||
height: 1240px;
|
||||
position: relative;
|
||||
background-size: cover;
|
||||
font-family: 'fzrzFont';
|
||||
padding: 20px;
|
||||
background-color: #E08A9F;
|
||||
border-radius: 50px;
|
||||
padding: 40px;
|
||||
color: #E08A9F;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.main{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
background-color: white;
|
||||
height: 1123px;
|
||||
width: 682px;
|
||||
border-radius: 50px;
|
||||
padding: 56px 83px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.weather-img {
|
||||
position: absolute;
|
||||
height: 60px;
|
||||
left: 325px;
|
||||
top: -10px;
|
||||
}
|
||||
|
||||
.top-date {
|
||||
display: flex;
|
||||
position: relative;
|
||||
font-family: "systFont";
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
margin-top: 65px;
|
||||
}
|
||||
|
||||
.user-info-ava {
|
||||
position: relative;
|
||||
|
||||
}
|
||||
|
||||
.ava-img {
|
||||
height: 250px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
border: 2px solid #E0899E;
|
||||
}
|
||||
|
||||
.user-info-data {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.nickname {
|
||||
position: absolute;
|
||||
width: 140px;
|
||||
left: 50%;
|
||||
bottom: -27px;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: #E0899E;
|
||||
color: white;
|
||||
padding: 5px 10px;
|
||||
border-radius: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.user-des {
|
||||
margin-top: 60px;
|
||||
font-size: 35px;
|
||||
position: relative;
|
||||
height: 710px;
|
||||
}
|
||||
|
||||
.des-img {
|
||||
height: 430px;
|
||||
position: absolute;
|
||||
bottom: -28px;
|
||||
left: 85px;
|
||||
}
|
||||
|
||||
.tag-img-content {
|
||||
height: 120px;
|
||||
width: 75px;
|
||||
background-color: #E8BB88;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 120px;
|
||||
}
|
||||
|
||||
.tag-img-test {
|
||||
border-left: 37px solid transparent;
|
||||
border-right: 38px solid transparent;
|
||||
border-bottom: 54px solid white;
|
||||
width: 0;
|
||||
height: 68px;
|
||||
}
|
||||
|
||||
.menu {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
height: 496px;
|
||||
top: 175px;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
writing-mode: vertical-rl; /* 从右向左垂直排列 */
|
||||
color: #754E43;
|
||||
height: 190px;
|
||||
width: 65px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 30px;
|
||||
border-top-left-radius: 30px;
|
||||
border-bottom-left-radius: 30px;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.main-img {
|
||||
position: absolute;
|
||||
height: 200px;
|
||||
right: 150px;
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
.sign-data {
|
||||
margin-top: 105px;
|
||||
}
|
||||
|
||||
.base-title {
|
||||
font-size: 35px;
|
||||
}
|
||||
|
||||
.sign-level {
|
||||
border: 2px solid #E08A9F;
|
||||
padding: 7px 3px;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.line {
|
||||
border: 1px solid #E08A9F;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.text-item {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
|
||||
.test-icon {
|
||||
height: 50px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.test-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.test-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.text-chart {
|
||||
margin-top: 20px;
|
||||
background-color: #E0899E;
|
||||
color: white;
|
||||
padding: 30px;
|
||||
border-radius: 30px;
|
||||
height: 560px;
|
||||
}
|
||||
|
||||
.chart {
|
||||
height: 490px;
|
||||
width: 622px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.select {
|
||||
background-color: #E0899E;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.uname {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1; /* 显示的最大行数 */
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden; /* 隐藏溢出内容 */
|
||||
text-overflow: ellipsis; /* 溢出部分显示为省略号 */
|
||||
}
|
||||
177
resources/template/my_info/main.html
Normal file
@ -0,0 +1,177 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.bootcss.com/echarts/4.2.1/echarts.min.js"></script>
|
||||
<title>test</title>
|
||||
<!-- <link rel="stylesheet" href="./res/font-awesome/css/font-awesome.min.css"> -->
|
||||
<link rel="stylesheet" href="main.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<div class="main">
|
||||
<div class="main-content">
|
||||
<div class="top-date">{{data.date}}......
|
||||
<img src="./res/img/{{data.weather}}.png" alt="sun" class="weather-img" />
|
||||
<span style="margin-left: 180px;">24℃</span>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="user-info-ava">
|
||||
<img src="{{data.ava_url}}" alt="test" class="ava-img" />
|
||||
<div class="nickname">{{data.title}}</div>
|
||||
</div>
|
||||
<div class="user-info-data">
|
||||
<div class="uname">
|
||||
<span style="font-size: 35px;">姓名:</span>
|
||||
<span>{{data.nickname}}</span>
|
||||
</div>
|
||||
<div style="margin-top: 15px;">
|
||||
<span style="font-size: 35px;">种族:</span>
|
||||
<span>{{data.race}}</span>
|
||||
</div>
|
||||
<div style="margin-top: 15px;">
|
||||
<span style="font-size: 35px;">性别:</span>
|
||||
<span>{{data.sex}}</span>
|
||||
</div>
|
||||
<div style="margin-top: 15px;">
|
||||
<span style="font-size: 35px;">职业:</span>
|
||||
<span>{{data.occ}}</span>
|
||||
</div>
|
||||
<div style="margin-top: 15px;">
|
||||
<span style="font-size: 35px;">UID:</span>
|
||||
<span>{{data.uid}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-des">
|
||||
<p>个人简介:</p>
|
||||
<div style="line-height: 60px;">
|
||||
{{data.description}}
|
||||
</div>
|
||||
<img src="./res/img/1.png" class="des-img" />
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 50px;"></div>
|
||||
<div class="main-content">
|
||||
<div class="menu">
|
||||
<div class="menu-item" style="background-color: #E8BC89;">我的信息</div>
|
||||
<div class="menu-item" style="background-color: #EDCCC3;">我的道具</div>
|
||||
<div class="menu-item" style="background-color: #F0DAC6;">我的卡组</div>
|
||||
<div class="menu-item" style="background-color: #F7E5E4;">我的设置</div>
|
||||
</div>
|
||||
<div class="tag-img">
|
||||
<div class="tag-img-content">
|
||||
<div class="tag-img-test"></div>
|
||||
</div>
|
||||
</div>
|
||||
<img src="./res/img/2.png" class="main-img" />
|
||||
<div class="sign-data">
|
||||
<p class="base-title">好感度等级: {{data.sign_level}}级</p>
|
||||
<div>
|
||||
<span class="sign-level {{data.select_index[0]}}">路人</span>
|
||||
<span class="sign-level {{data.select_index[1]}}">陌生</span>
|
||||
<span class="sign-level {{data.select_index[2]}}">初识</span>
|
||||
<span class="sign-level {{data.select_index[3]}}">普通</span>
|
||||
<span class="sign-level {{data.select_index[4]}}">熟悉</span>
|
||||
<span class="sign-level {{data.select_index[5]}}">信赖</span>
|
||||
<span class="sign-level {{data.select_index[6]}}">相知</span>
|
||||
<span class="sign-level {{data.select_index[7]}}">厚谊</span>
|
||||
<span class="sign-level {{data.select_index[8]}}">亲密</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<div class="test-content" style="margin-top: 30px">
|
||||
<img src="./res/img/level.png" class="test-icon" />
|
||||
权限等级: {{data.level}}
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-item">
|
||||
<div class="test-content" style="width: 50%;">
|
||||
<img src="./res/img/gold.png" class="test-icon" />
|
||||
金币数量: {{data.gold}}
|
||||
</div>
|
||||
<div class="test-content">
|
||||
<img src="./res/img/prop.png" class="test-icon" />
|
||||
道具数量: {{data.prop}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<div class="test-content" style="width: 50%;">
|
||||
<img src="./res/img/call.png" class="test-icon" />
|
||||
调用次数: {{data.call}}
|
||||
</div>
|
||||
<div class="test-content">
|
||||
<img src="./res/img/say.png" class="test-icon" />
|
||||
发言统计: {{data.say}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="line"></div> -->
|
||||
<div class="text-chart">
|
||||
<div class="test-title">
|
||||
<img src="./res/img/xian.png" class="test-icon" />
|
||||
发言趋势图
|
||||
</div>
|
||||
<div id="chart" class="chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
// 基于准备好的dom,初始化echarts实例
|
||||
var myChart = echarts.init(document.getElementById('chart'));
|
||||
// 指定图表的配置项和数据
|
||||
var option = {
|
||||
backgroundColor: "#E0899E",
|
||||
animation: false,
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: {{data.chart_date|tojson}},
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 20,
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
fontSize: 20,
|
||||
},
|
||||
},
|
||||
series: [{
|
||||
data: {{data.count_list|tojson}},
|
||||
type: "line",
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
// 设置线条颜色
|
||||
color: '#fff',
|
||||
// 可选:设置线条宽度
|
||||
width: 2
|
||||
},
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
textStyle: {
|
||||
fontSize: 20,
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
}
|
||||
}, ],
|
||||
};
|
||||
|
||||
|
||||
// 使用刚指定的配置项和数据显示图表。
|
||||
myChart.setOption(option);
|
||||
</script>
|
||||
</body>
|
||||
<script type="text/javascript" src="main.js">
|
||||
</script>
|
||||
|
||||
</html>
|
||||
32
resources/template/my_info/main.js
Normal file
@ -0,0 +1,32 @@
|
||||
// var chartDom = document.getElementById("chart")
|
||||
// var myChart = echarts.init(chartDom)
|
||||
// var option
|
||||
|
||||
// option = {
|
||||
// backgroundColor: "#E0899E",
|
||||
// animation: false,
|
||||
// xAxis: {
|
||||
// type: "category",
|
||||
// data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
||||
// axisLabel: {
|
||||
// color: "#fff",
|
||||
// fontSize: 20,
|
||||
// },
|
||||
// },
|
||||
// yAxis: {
|
||||
// type: "value",
|
||||
// axisLabel: {
|
||||
// color: "#fff",
|
||||
// fontSize: 20,
|
||||
// },
|
||||
// },
|
||||
// series: [
|
||||
// {
|
||||
// data: [820, 932, 901, 934, 1290, 1330, 1320],
|
||||
// type: "line",
|
||||
// smooth: true,
|
||||
// },
|
||||
// ],
|
||||
// }
|
||||
|
||||
// option && myChart.setOption(option)
|
||||
130
resources/template/my_info/main_copy.html
Normal file
@ -0,0 +1,130 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.jsdelivr.net/npm/echarts@latest/dist/echarts.min.js"></script>
|
||||
<title>test</title>
|
||||
<!-- <link rel="stylesheet" href="./res/font-awesome/css/font-awesome.min.css"> -->
|
||||
<link rel="stylesheet" href="main.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<div class="main">
|
||||
<div class="main-content">
|
||||
<div class="top-date">2024/08/14......
|
||||
<img src="./res/img/sun.png" alt="sun" class="weather-img" />
|
||||
<span style="margin-left: 180px;">24℃</span>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="user-info-ava">
|
||||
<img src="./res/img/test.jpg" alt="test" class="ava-img" />
|
||||
<div class="nickname">勇 者</div>
|
||||
</div>
|
||||
<div class="user-info-data">
|
||||
<div>
|
||||
<span style="font-size: 35px;">姓名:</span>
|
||||
<span>副驾驶啦啦啦</span>
|
||||
</div>
|
||||
<div style="margin-top: 15px;">
|
||||
<span style="font-size: 35px;">种族:</span>
|
||||
<span>人类</span>
|
||||
</div>
|
||||
<div style="margin-top: 15px;">
|
||||
<span style="font-size: 35px;">性别:</span>
|
||||
<span>男</span>
|
||||
</div>
|
||||
<div style="margin-top: 15px;">
|
||||
<span style="font-size: 35px;">生日:</span>
|
||||
<span>2021/10/01</span>
|
||||
</div>
|
||||
<div style="margin-top: 15px;">
|
||||
<span style="font-size: 35px;">UID:</span>
|
||||
<span>0021</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-des">
|
||||
<p>个人简介:</p>
|
||||
<div style="line-height: 60px;">
|
||||
这是人类勇者的传奇在这片古老而神秘的土地上,
|
||||
每当黑暗的力量威胁到和平与正义之时总会有一位英雄挺身而出。
|
||||
他们不仅拥有超凡的力量更重要的是更重要的是更重要的是
|
||||
</div>
|
||||
<img src="./res/img/1.png" class="des-img" />
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 50px;"></div>
|
||||
<div class="main-content">
|
||||
<div class="menu">
|
||||
<div class="menu-item" style="background-color: #E8BC89;">信息</div>
|
||||
<div class="menu-item" style="background-color: #EDCCC3;">仓库</div>
|
||||
<div class="menu-item" style="background-color: #F0DAC6;">卡组</div>
|
||||
<div class="menu-item" style="background-color: #F7E5E4;">设置</div>
|
||||
</div>
|
||||
<div class="tag-img">
|
||||
<div class="tag-img-content">
|
||||
<div class="tag-img-test"></div>
|
||||
</div>
|
||||
</div>
|
||||
<img src="./res/img/2.png" class="main-img" />
|
||||
<div class="sign-data">
|
||||
<p class="base-title">好感度等级: 5级</p>
|
||||
<div>
|
||||
<span class="sign-level">路人</span>
|
||||
<span class="sign-level">陌生</span>
|
||||
<span class="sign-level">初识</span>
|
||||
<span class="sign-level select">普通</span>
|
||||
<span class="sign-level">熟悉</span>
|
||||
<span class="sign-level">信赖</span>
|
||||
<span class="sign-level">相知</span>
|
||||
<span class="sign-level">厚谊</span>
|
||||
<span class="sign-level">亲密</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<div class="test-content" style="margin-top: 30px">
|
||||
<img src="./res/img/level.png" class="test-icon" />
|
||||
权限等级: 9
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-item">
|
||||
<div class="test-content" style="width: 50%;">
|
||||
<img src="./res/img/gold.png" class="test-icon" />
|
||||
金币数量: 999
|
||||
</div>
|
||||
<div class="test-content">
|
||||
<img src="./res/img/prop.png" class="test-icon" />
|
||||
道具数量: 933
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<div class="test-content" style="width: 50%;">
|
||||
<img src="./res/img/call.png" class="test-icon" />
|
||||
调用次数: 6443
|
||||
</div>
|
||||
<div class="test-content">
|
||||
<img src="./res/img/say.png" class="test-icon" />
|
||||
发言统计: 233
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="line"></div> -->
|
||||
<div class="text-chart">
|
||||
<div class="test-title">
|
||||
<img src="./res/img/xian.png" class="test-icon" />
|
||||
发言趋势图
|
||||
</div>
|
||||
<div id="chart" class="chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="text/javascript" src="main.js">
|
||||
</script>
|
||||
|
||||
</html>
|
||||
BIN
resources/template/my_info/res/img/1.png
Normal file
|
After Width: | Height: | Size: 777 KiB |
BIN
resources/template/my_info/res/img/2.png
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
resources/template/my_info/res/img/3.jpg
Normal file
|
After Width: | Height: | Size: 483 KiB |
BIN
resources/template/my_info/res/img/call.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
resources/template/my_info/res/img/gold.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
resources/template/my_info/res/img/level.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
resources/template/my_info/res/img/moon.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
resources/template/my_info/res/img/prop.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
resources/template/my_info/res/img/say.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
resources/template/my_info/res/img/sun.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
resources/template/my_info/res/img/test.jpg
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
resources/template/my_info/res/img/xian.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
@ -34,11 +34,6 @@
|
||||
src: url("./res/font/jcyt.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: yshsFont;
|
||||
/* 导入的字体文件 */
|
||||
src: url("/resources/font/YSHaoShenTi-2.ttf");
|
||||
}
|
||||
|
||||
body {
|
||||
position: absolute;
|
||||
@ -79,10 +74,17 @@ body {
|
||||
margin-top: 43px;
|
||||
margin-left: 30px;
|
||||
font-size: 47px;
|
||||
height: 57px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: flex
|
||||
/* align-items: center;
|
||||
justify-content: center; */
|
||||
/* display: flex; */
|
||||
width: 275px;
|
||||
height: 67px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.uid {
|
||||
@ -122,6 +124,7 @@ body {
|
||||
position: absolute;
|
||||
top: 72px;
|
||||
left: 130px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.sign-content{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
|
||||
</html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
@ -10,12 +10,13 @@
|
||||
<!-- <link rel="stylesheet" href="./res/font-awesome/css/font-awesome.min.css"> -->
|
||||
<link rel="stylesheet" href="main.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<div class="top-head">
|
||||
<div style="display: flex;">
|
||||
<div class="avatar">
|
||||
<img class="avatar-img" src="{{data.ava}}" alt="">
|
||||
<img class="avatar-img" src="{{data.ava_url}}" alt="">
|
||||
</div>
|
||||
<div style="position: relative;">
|
||||
<p class="nickname" style="font-size: {{ data.font_size }}px;">{{data.name}}</p>
|
||||
@ -40,20 +41,21 @@
|
||||
<p class="gift">{{data.impression}}</p>
|
||||
</div>
|
||||
<div class="abs-text" style="top: 83px;">
|
||||
<p class="gift">{{data.gold}}</p></div>
|
||||
<div class="abs-text" style="top: 123px;">
|
||||
<p class="gift">{{data.gold}}</p>
|
||||
</div>
|
||||
<div class="abs-text" style="top: 123px;">
|
||||
<p class="gift">{{data.gift}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<div class="bottom-foot">
|
||||
<p class="cur-text">当前好感度: {{data.cur_impression}}</p>
|
||||
<div class="heart-list">
|
||||
{% for i in data.heart2 %}
|
||||
<img class="heart-img" src="res/img/h2.png" alt=""/>
|
||||
<img class="heart-img" src="res/img/h2.png" alt="" />
|
||||
{% endfor %}
|
||||
{% for i in data.heart1 %}
|
||||
<img class="heart-img" src="res/img/h1.png" alt=""/>
|
||||
<img class="heart-img" src="res/img/h1.png" alt="" />
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="bot-text">
|
||||
@ -61,11 +63,11 @@
|
||||
<p style="position: absolute; top: 58px">{{data.attitude}}</p>
|
||||
<p style="position: absolute; top: 111px"">距离升级还差{{data.interpolation}}好感度</p>
|
||||
</div>
|
||||
<div class="progress-border">
|
||||
<div class="progress-bar" style="width: {{ data.process }}%;"></div>
|
||||
<div class=" progress-border">
|
||||
<div class="progress-bar" style="width: {{ data.process }}%;"></div>
|
||||
</div>
|
||||
<img class="weather-img" src="res/img/weather/0.png" alt="">
|
||||
<p class="wd" >28℃</p>
|
||||
<p class="wd">28℃</p>
|
||||
<img class="mbl-img" src="res/img/2.png" alt="">
|
||||
<div class="date">
|
||||
{{data.date}}
|
||||
@ -75,4 +77,5 @@
|
||||
</body>
|
||||
<script type="text/javascript" src="main.js">
|
||||
</script>
|
||||
|
||||
</html>
|
||||
@ -3,19 +3,19 @@
|
||||
@font-face {
|
||||
font-family: fzrzFont;
|
||||
/* 导入的字体文件 */
|
||||
src: url("./res/font/fzrzExtraBold.ttf");
|
||||
src: url("../../font/fzrzExtraBold.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: syhtFont;
|
||||
/* 导入的字体文件 */
|
||||
src: url("./res/font/syht.otf");
|
||||
src: url("../../font/syht.otf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: systFont;
|
||||
/* 导入的字体文件 */
|
||||
src: url("./res/font/syst.otf");
|
||||
src: url("../../font/syst.otf");
|
||||
}
|
||||
|
||||
|
||||
|
||||
529
tests/builtin_plugins/auto_update/test_check_update.py
Normal file
@ -0,0 +1,529 @@
|
||||
import io
|
||||
import os
|
||||
import tarfile
|
||||
import zipfile
|
||||
from typing import cast
|
||||
from pathlib import Path
|
||||
from collections.abc import Callable
|
||||
|
||||
from nonebug import App
|
||||
from respx import MockRouter
|
||||
from pytest_mock import MockerFixture
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from nonebot.adapters.onebot.v11.message import Message
|
||||
|
||||
from tests.config import BotId, UserId, GroupId, MessageId
|
||||
from tests.utils import get_response_json as _get_response_json
|
||||
from tests.utils import _v11_group_message_event, _v11_private_message_send
|
||||
|
||||
|
||||
def get_response_json(file: str) -> dict:
|
||||
return _get_response_json(Path() / "auto_update", file)
|
||||
|
||||
|
||||
def init_mocked_api(mocked_api: MockRouter) -> None:
|
||||
mocked_api.get(
|
||||
url="https://api.github.com/repos/HibiKier/zhenxun_bot/releases/latest",
|
||||
name="release_latest",
|
||||
).respond(json=get_response_json("release_latest.json"))
|
||||
|
||||
mocked_api.head(
|
||||
url="https://raw.githubusercontent.com/",
|
||||
name="head_raw",
|
||||
).respond(text="")
|
||||
mocked_api.head(
|
||||
url="https://github.com/",
|
||||
name="head_github",
|
||||
).respond(text="")
|
||||
mocked_api.head(
|
||||
url="https://codeload.github.com/",
|
||||
name="head_codeload",
|
||||
).respond(text="")
|
||||
|
||||
mocked_api.get(
|
||||
url="https://raw.githubusercontent.com/HibiKier/zhenxun_bot/dev/__version__",
|
||||
name="dev_branch_version",
|
||||
).respond(text="__version__: v0.2.2-e6f17c4")
|
||||
mocked_api.get(
|
||||
url="https://raw.githubusercontent.com/HibiKier/zhenxun_bot/main/__version__",
|
||||
name="main_branch_version",
|
||||
).respond(text="__version__: v0.2.2-e6f17c4")
|
||||
mocked_api.get(
|
||||
url="https://api.github.com/repos/HibiKier/zhenxun_bot/tarball/v0.2.2",
|
||||
name="release_download_url",
|
||||
).respond(
|
||||
status_code=302,
|
||||
headers={
|
||||
"Location": "https://codeload.github.com/HibiKier/zhenxun_bot/legacy.tar.gz/refs/tags/v0.2.2"
|
||||
},
|
||||
)
|
||||
|
||||
tar_buffer = io.BytesIO()
|
||||
zip_bytes = io.BytesIO()
|
||||
|
||||
from zhenxun.builtin_plugins.auto_update.config import (
|
||||
REPLACE_FOLDERS,
|
||||
REQ_TXT_FILE_STRING,
|
||||
PYPROJECT_FILE_STRING,
|
||||
PYPROJECT_LOCK_FILE_STRING,
|
||||
)
|
||||
|
||||
# 指定要添加到压缩文件中的文件路径列表
|
||||
file_paths: list[str] = [
|
||||
PYPROJECT_FILE_STRING,
|
||||
PYPROJECT_LOCK_FILE_STRING,
|
||||
REQ_TXT_FILE_STRING,
|
||||
]
|
||||
|
||||
# 打开一个tarfile对象,写入到上面创建的BytesIO对象中
|
||||
with tarfile.open(mode="w:gz", fileobj=tar_buffer) as tar:
|
||||
add_files_and_folders_to_tar(tar, file_paths, folders=REPLACE_FOLDERS)
|
||||
|
||||
with zipfile.ZipFile(zip_bytes, mode="w", compression=zipfile.ZIP_DEFLATED) as zipf:
|
||||
add_files_and_folders_to_zip(zipf, file_paths, folders=REPLACE_FOLDERS)
|
||||
|
||||
mocked_api.get(
|
||||
url="https://codeload.github.com/HibiKier/zhenxun_bot/legacy.tar.gz/refs/tags/v0.2.2",
|
||||
name="release_download_url_redirect",
|
||||
).respond(
|
||||
content=tar_buffer.getvalue(),
|
||||
)
|
||||
mocked_api.get(
|
||||
url="https://github.com/HibiKier/zhenxun_bot/archive/refs/heads/dev.zip",
|
||||
name="dev_download_url",
|
||||
).respond(
|
||||
content=zip_bytes.getvalue(),
|
||||
)
|
||||
mocked_api.get(
|
||||
url="https://github.com/HibiKier/zhenxun_bot/archive/refs/heads/main.zip",
|
||||
name="main_download_url",
|
||||
).respond(
|
||||
content=zip_bytes.getvalue(),
|
||||
)
|
||||
|
||||
|
||||
# TODO Rename this here and in `init_mocked_api`
|
||||
def add_files_and_folders_to_zip(
|
||||
zipf: zipfile.ZipFile, file_paths: list[str], folders: list[str] = []
|
||||
):
|
||||
"""Add files and folders to a zip archive.
|
||||
|
||||
This function creates a directory structure within the specified zip
|
||||
archive and adds the provided files to it. It also creates additional
|
||||
subdirectories as specified in the folders list.
|
||||
|
||||
Args:
|
||||
zipf: The zip archive to which files and folders will be added.
|
||||
file_paths: A list of file names to be added to the zip archive.
|
||||
folders: An optional list of subdirectory names to be created
|
||||
within the base folder.
|
||||
"""
|
||||
|
||||
# 假设有一个文件夹名为 folder_name
|
||||
folder_name = "my_folder/"
|
||||
|
||||
# 添加文件夹到 ZIP 中,注意 ZIP 中文件夹路径应以 '/' 结尾
|
||||
zipf.writestr(folder_name, "") # 空内容表示这是一个文件夹
|
||||
|
||||
for file_path in file_paths:
|
||||
# 将文件添加到 ZIP 中,路径为 folder_name + file_name
|
||||
zipf.writestr(f"{folder_name}{os.path.basename(file_path)}", b"new")
|
||||
base_folder = f"{folder_name}zhenxun/"
|
||||
zipf.writestr(base_folder, "")
|
||||
|
||||
for folder in folders:
|
||||
zipf.writestr(f"{base_folder}{folder}/", "")
|
||||
|
||||
|
||||
# TODO Rename this here and in `init_mocked_api`
|
||||
def add_files_and_folders_to_tar(
|
||||
tar: tarfile.TarFile, file_paths: list[str], folders: list[str] = []
|
||||
):
|
||||
"""Add files and folders to a tar archive.
|
||||
|
||||
This function creates a directory structure within the specified tar
|
||||
archive and adds the provided files to it. It also creates additional
|
||||
subdirectories as specified in the folders list.
|
||||
|
||||
Args:
|
||||
tar: The tar archive to which files and folders will be added.
|
||||
file_paths: A list of file names to be added to the tar archive.
|
||||
folders: An optional list of subdirectory names to be created
|
||||
within the base folder.
|
||||
"""
|
||||
|
||||
folder_name = "my_folder"
|
||||
tarinfo = tarfile.TarInfo(folder_name)
|
||||
add_directory_to_tar(tarinfo, tar)
|
||||
# 读取并添加指定的文件
|
||||
for file_path in file_paths:
|
||||
# 创建TarInfo对象
|
||||
tar_buffer = io.BytesIO(b"new")
|
||||
tarinfo = tarfile.TarInfo(
|
||||
f"{folder_name}/{file_path}"
|
||||
) # 使用文件名作为tar中的名字
|
||||
tarinfo.mode = 0o644 # 设置文件夹权限
|
||||
tarinfo.size = len(tar_buffer.getvalue()) # 设置文件大小
|
||||
|
||||
# 添加文件
|
||||
tar.addfile(tarinfo, fileobj=tar_buffer)
|
||||
|
||||
base_folder = f"{folder_name}/zhenxun"
|
||||
tarinfo = tarfile.TarInfo(base_folder)
|
||||
add_directory_to_tar(tarinfo, tar)
|
||||
for folder in folders:
|
||||
tarinfo = tarfile.TarInfo(f"{base_folder}{folder}")
|
||||
add_directory_to_tar(tarinfo, tar)
|
||||
|
||||
|
||||
# TODO Rename this here and in `_extracted_from_init_mocked_api_43`
|
||||
def add_directory_to_tar(tarinfo, tar):
|
||||
"""Add a directory entry to a tar archive.
|
||||
|
||||
This function modifies the provided tarinfo object to set its type
|
||||
as a directory and assigns the appropriate permissions before adding
|
||||
it to the specified tar archive.
|
||||
|
||||
Args:
|
||||
tarinfo: The tarinfo object representing the directory.
|
||||
tar: The tar archive to which the directory will be added.
|
||||
"""
|
||||
|
||||
tarinfo.type = tarfile.DIRTYPE
|
||||
tarinfo.mode = 0o755
|
||||
tar.addfile(tarinfo)
|
||||
|
||||
|
||||
def init_mocker_path(mocker: MockerFixture, tmp_path: Path):
|
||||
from zhenxun.builtin_plugins.auto_update.config import (
|
||||
REQ_TXT_FILE_STRING,
|
||||
VERSION_FILE_STRING,
|
||||
PYPROJECT_FILE_STRING,
|
||||
PYPROJECT_LOCK_FILE_STRING,
|
||||
)
|
||||
|
||||
mocker.patch(
|
||||
"zhenxun.builtin_plugins.auto_update._data_source.install_requirement",
|
||||
return_value=None,
|
||||
)
|
||||
mock_tmp_path = mocker.patch(
|
||||
"zhenxun.builtin_plugins.auto_update._data_source.TMP_PATH",
|
||||
new=tmp_path / "auto_update",
|
||||
)
|
||||
mock_base_path = mocker.patch(
|
||||
"zhenxun.builtin_plugins.auto_update._data_source.BASE_PATH",
|
||||
new=tmp_path / "zhenxun",
|
||||
)
|
||||
mock_backup_path = mocker.patch(
|
||||
"zhenxun.builtin_plugins.auto_update._data_source.BACKUP_PATH",
|
||||
new=tmp_path / "backup",
|
||||
)
|
||||
mock_download_gz_file = mocker.patch(
|
||||
"zhenxun.builtin_plugins.auto_update._data_source.DOWNLOAD_GZ_FILE",
|
||||
new=mock_tmp_path / "download_latest_file.tar.gz",
|
||||
)
|
||||
mock_download_zip_file = mocker.patch(
|
||||
"zhenxun.builtin_plugins.auto_update._data_source.DOWNLOAD_ZIP_FILE",
|
||||
new=mock_tmp_path / "download_latest_file.zip",
|
||||
)
|
||||
mock_pyproject_file = mocker.patch(
|
||||
"zhenxun.builtin_plugins.auto_update._data_source.PYPROJECT_FILE",
|
||||
new=tmp_path / PYPROJECT_FILE_STRING,
|
||||
)
|
||||
mock_pyproject_lock_file = mocker.patch(
|
||||
"zhenxun.builtin_plugins.auto_update._data_source.PYPROJECT_LOCK_FILE",
|
||||
new=tmp_path / PYPROJECT_LOCK_FILE_STRING,
|
||||
)
|
||||
mock_req_txt_file = mocker.patch(
|
||||
"zhenxun.builtin_plugins.auto_update._data_source.REQ_TXT_FILE",
|
||||
new=tmp_path / REQ_TXT_FILE_STRING,
|
||||
)
|
||||
mock_version_file = mocker.patch(
|
||||
"zhenxun.builtin_plugins.auto_update._data_source.VERSION_FILE",
|
||||
new=tmp_path / VERSION_FILE_STRING,
|
||||
)
|
||||
open(mock_version_file, "w").write("__version__: v0.2.2")
|
||||
return (
|
||||
mock_tmp_path,
|
||||
mock_base_path,
|
||||
mock_backup_path,
|
||||
mock_download_gz_file,
|
||||
mock_download_zip_file,
|
||||
mock_pyproject_file,
|
||||
mock_pyproject_lock_file,
|
||||
mock_req_txt_file,
|
||||
mock_version_file,
|
||||
)
|
||||
|
||||
|
||||
async def test_check_update_release(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试检查更新(release)
|
||||
"""
|
||||
from zhenxun.builtin_plugins.auto_update import _matcher
|
||||
from zhenxun.builtin_plugins.auto_update.config import (
|
||||
REPLACE_FOLDERS,
|
||||
REQ_TXT_FILE_STRING,
|
||||
PYPROJECT_FILE_STRING,
|
||||
PYPROJECT_LOCK_FILE_STRING,
|
||||
)
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
|
||||
(
|
||||
mock_tmp_path,
|
||||
mock_base_path,
|
||||
mock_backup_path,
|
||||
mock_download_gz_file,
|
||||
mock_download_zip_file,
|
||||
mock_pyproject_file,
|
||||
mock_pyproject_lock_file,
|
||||
mock_req_txt_file,
|
||||
mock_version_file,
|
||||
) = init_mocker_path(mocker, tmp_path)
|
||||
|
||||
# 确保目录下有一个子目录,以便 os.listdir() 能返回一个目录名
|
||||
mock_tmp_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for folder in REPLACE_FOLDERS:
|
||||
(mock_base_path / folder).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
mock_pyproject_file.write_bytes(b"")
|
||||
mock_pyproject_lock_file.write_bytes(b"")
|
||||
mock_req_txt_file.write_bytes(b"")
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot = cast(Bot, bot)
|
||||
raw_message = "检查更新 release"
|
||||
event = _v11_group_message_event(
|
||||
raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot, event)
|
||||
ctx.should_call_api(
|
||||
"send_msg",
|
||||
_v11_private_message_send(
|
||||
message="检测真寻已更新,版本更新:v0.2.2 -> v0.2.2\n" "开始更新...",
|
||||
user_id=UserId.SUPERUSER,
|
||||
),
|
||||
)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(
|
||||
"版本更新完成\n" "版本: v0.2.2 -> v0.2.2\n" "请重新启动真寻以完成更新!"
|
||||
),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
ctx.should_finished(_matcher)
|
||||
assert mocked_api["release_latest"].called
|
||||
assert mocked_api["release_download_url_redirect"].called
|
||||
|
||||
assert (mock_backup_path / PYPROJECT_FILE_STRING).exists()
|
||||
assert (mock_backup_path / PYPROJECT_LOCK_FILE_STRING).exists()
|
||||
assert (mock_backup_path / REQ_TXT_FILE_STRING).exists()
|
||||
|
||||
assert not mock_download_gz_file.exists()
|
||||
assert not mock_download_zip_file.exists()
|
||||
|
||||
assert mock_pyproject_file.read_bytes() == b"new"
|
||||
assert mock_pyproject_lock_file.read_bytes() == b"new"
|
||||
assert mock_req_txt_file.read_bytes() == b"new"
|
||||
|
||||
for folder in REPLACE_FOLDERS:
|
||||
assert not (mock_base_path / folder).exists()
|
||||
for folder in REPLACE_FOLDERS:
|
||||
assert (mock_backup_path / folder).exists()
|
||||
|
||||
|
||||
async def test_check_update_dev(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试检查更新(开发环境)
|
||||
"""
|
||||
from zhenxun.builtin_plugins.auto_update import _matcher
|
||||
from zhenxun.builtin_plugins.auto_update.config import (
|
||||
REPLACE_FOLDERS,
|
||||
REQ_TXT_FILE_STRING,
|
||||
PYPROJECT_FILE_STRING,
|
||||
PYPROJECT_LOCK_FILE_STRING,
|
||||
)
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
|
||||
(
|
||||
mock_tmp_path,
|
||||
mock_base_path,
|
||||
mock_backup_path,
|
||||
mock_download_gz_file,
|
||||
mock_download_zip_file,
|
||||
mock_pyproject_file,
|
||||
mock_pyproject_lock_file,
|
||||
mock_req_txt_file,
|
||||
mock_version_file,
|
||||
) = init_mocker_path(mocker, tmp_path)
|
||||
|
||||
# 确保目录下有一个子目录,以便 os.listdir() 能返回一个目录名
|
||||
mock_tmp_path.mkdir(parents=True, exist_ok=True)
|
||||
for folder in REPLACE_FOLDERS:
|
||||
(mock_base_path / folder).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
mock_pyproject_file.write_bytes(b"")
|
||||
mock_pyproject_lock_file.write_bytes(b"")
|
||||
mock_req_txt_file.write_bytes(b"")
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot = cast(Bot, bot)
|
||||
raw_message = "检查更新 dev"
|
||||
event = _v11_group_message_event(
|
||||
raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot, event)
|
||||
ctx.should_call_api(
|
||||
"send_msg",
|
||||
_v11_private_message_send(
|
||||
message="检测真寻已更新,版本更新:v0.2.2 -> v0.2.2-e6f17c4\n"
|
||||
"开始更新...",
|
||||
user_id=UserId.SUPERUSER,
|
||||
),
|
||||
)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(
|
||||
"版本更新完成\n"
|
||||
"版本: v0.2.2 -> v0.2.2-e6f17c4\n"
|
||||
"请重新启动真寻以完成更新!"
|
||||
),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
ctx.should_finished(_matcher)
|
||||
assert mocked_api["dev_download_url"].called
|
||||
assert (mock_backup_path / PYPROJECT_FILE_STRING).exists()
|
||||
assert (mock_backup_path / PYPROJECT_LOCK_FILE_STRING).exists()
|
||||
assert (mock_backup_path / REQ_TXT_FILE_STRING).exists()
|
||||
|
||||
assert not mock_download_gz_file.exists()
|
||||
assert not mock_download_zip_file.exists()
|
||||
|
||||
assert mock_pyproject_file.read_bytes() == b"new"
|
||||
assert mock_pyproject_lock_file.read_bytes() == b"new"
|
||||
assert mock_req_txt_file.read_bytes() == b"new"
|
||||
|
||||
for folder in REPLACE_FOLDERS:
|
||||
assert (mock_base_path / folder).exists()
|
||||
for folder in REPLACE_FOLDERS:
|
||||
assert (mock_backup_path / folder).exists()
|
||||
|
||||
|
||||
async def test_check_update_main(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试检查更新(正式环境)
|
||||
"""
|
||||
from zhenxun.builtin_plugins.auto_update import _matcher
|
||||
from zhenxun.builtin_plugins.auto_update.config import (
|
||||
REPLACE_FOLDERS,
|
||||
REQ_TXT_FILE_STRING,
|
||||
PYPROJECT_FILE_STRING,
|
||||
PYPROJECT_LOCK_FILE_STRING,
|
||||
)
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
|
||||
(
|
||||
mock_tmp_path,
|
||||
mock_base_path,
|
||||
mock_backup_path,
|
||||
mock_download_gz_file,
|
||||
mock_download_zip_file,
|
||||
mock_pyproject_file,
|
||||
mock_pyproject_lock_file,
|
||||
mock_req_txt_file,
|
||||
mock_version_file,
|
||||
) = init_mocker_path(mocker, tmp_path)
|
||||
|
||||
# 确保目录下有一个子目录,以便 os.listdir() 能返回一个目录名
|
||||
mock_tmp_path.mkdir(parents=True, exist_ok=True)
|
||||
for folder in REPLACE_FOLDERS:
|
||||
(mock_base_path / folder).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
mock_pyproject_file.write_bytes(b"")
|
||||
mock_pyproject_lock_file.write_bytes(b"")
|
||||
mock_req_txt_file.write_bytes(b"")
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot = cast(Bot, bot)
|
||||
raw_message = "检查更新 main"
|
||||
event = _v11_group_message_event(
|
||||
raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot, event)
|
||||
ctx.should_call_api(
|
||||
"send_msg",
|
||||
_v11_private_message_send(
|
||||
message="检测真寻已更新,版本更新:v0.2.2 -> v0.2.2-e6f17c4\n"
|
||||
"开始更新...",
|
||||
user_id=UserId.SUPERUSER,
|
||||
),
|
||||
)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(
|
||||
"版本更新完成\n"
|
||||
"版本: v0.2.2 -> v0.2.2-e6f17c4\n"
|
||||
"请重新启动真寻以完成更新!"
|
||||
),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
ctx.should_finished(_matcher)
|
||||
assert mocked_api["main_download_url"].called
|
||||
assert (mock_backup_path / PYPROJECT_FILE_STRING).exists()
|
||||
assert (mock_backup_path / PYPROJECT_LOCK_FILE_STRING).exists()
|
||||
assert (mock_backup_path / REQ_TXT_FILE_STRING).exists()
|
||||
|
||||
assert not mock_download_gz_file.exists()
|
||||
assert not mock_download_zip_file.exists()
|
||||
|
||||
assert mock_pyproject_file.read_bytes() == b"new"
|
||||
assert mock_pyproject_lock_file.read_bytes() == b"new"
|
||||
assert mock_req_txt_file.read_bytes() == b"new"
|
||||
|
||||
for folder in REPLACE_FOLDERS:
|
||||
assert (mock_base_path / folder).exists()
|
||||
for folder in REPLACE_FOLDERS:
|
||||
assert (mock_backup_path / folder).exists()
|
||||
231
tests/builtin_plugins/check/test_check.py
Normal file
@ -0,0 +1,231 @@
|
||||
import platform
|
||||
from typing import cast
|
||||
from pathlib import Path
|
||||
from collections.abc import Callable
|
||||
|
||||
import nonebot
|
||||
from nonebug import App
|
||||
from respx import MockRouter
|
||||
from pytest_mock import MockerFixture
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from nonebot.adapters.onebot.v11.event import GroupMessageEvent
|
||||
|
||||
from tests.utils import _v11_group_message_event
|
||||
from tests.config import BotId, UserId, GroupId, MessageId
|
||||
|
||||
platform_uname = platform.uname_result(
|
||||
system="Linux",
|
||||
node="zhenxun",
|
||||
release="5.15.0-1027-azure",
|
||||
version="#1 SMP Debian 5.15.0-1027-azure",
|
||||
machine="x86_64",
|
||||
) # type: ignore
|
||||
cpuinfo_get_cpu_info = {"brand_raw": "Intel(R) Core(TM) i7-10700K"}
|
||||
|
||||
|
||||
def init_mocker(mocker: MockerFixture, tmp_path: Path):
|
||||
mock_psutil = mocker.patch("zhenxun.builtin_plugins.check.data_source.psutil")
|
||||
mock_cpuinfo = mocker.patch("zhenxun.builtin_plugins.check.data_source.cpuinfo")
|
||||
mock_cpuinfo.get_cpu_info.return_value = cpuinfo_get_cpu_info
|
||||
|
||||
mock_platform = mocker.patch("zhenxun.builtin_plugins.check.data_source.platform")
|
||||
mock_platform.uname.return_value = platform_uname
|
||||
|
||||
mock_template_to_pic = mocker.patch("zhenxun.builtin_plugins.check.template_to_pic")
|
||||
mock_template_to_pic_return = mocker.AsyncMock()
|
||||
mock_template_to_pic.return_value = mock_template_to_pic_return
|
||||
|
||||
mock_build_message = mocker.patch(
|
||||
"zhenxun.builtin_plugins.check.MessageUtils.build_message"
|
||||
)
|
||||
mock_build_message_return = mocker.AsyncMock()
|
||||
mock_build_message.return_value = mock_build_message_return
|
||||
|
||||
mock_template_path_new = tmp_path / "resources" / "template"
|
||||
mocker.patch(
|
||||
"zhenxun.builtin_plugins.check.TEMPLATE_PATH", new=mock_template_path_new
|
||||
)
|
||||
return (
|
||||
mock_psutil,
|
||||
mock_cpuinfo,
|
||||
mock_platform,
|
||||
mock_template_to_pic,
|
||||
mock_template_to_pic_return,
|
||||
mock_build_message,
|
||||
mock_build_message_return,
|
||||
mock_template_path_new,
|
||||
)
|
||||
|
||||
|
||||
async def test_check(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试自检
|
||||
"""
|
||||
from zhenxun.configs.config import BotConfig
|
||||
from zhenxun.builtin_plugins.check import _matcher
|
||||
from zhenxun.builtin_plugins.check.data_source import __get_version
|
||||
|
||||
(
|
||||
mock_psutil,
|
||||
mock_cpuinfo,
|
||||
mock_platform,
|
||||
mock_template_to_pic,
|
||||
mock_template_to_pic_return,
|
||||
mock_build_message,
|
||||
mock_build_message_return,
|
||||
mock_template_path_new,
|
||||
) = init_mocker(mocker, tmp_path)
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = "自检"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID_3,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
mock_template_to_pic.assert_awaited_once_with(
|
||||
template_path=str((mock_template_path_new / "check").absolute()),
|
||||
template_name="main.html",
|
||||
templates={
|
||||
"data": {
|
||||
"cpu_info": "1.0% - 1.0Ghz [1 core]",
|
||||
"cpu_process": 1.0,
|
||||
"ram_info": "1.0 / 1.0 GB",
|
||||
"ram_process": 100.0,
|
||||
"swap_info": "1.0 / 1.0 GB",
|
||||
"swap_process": 100.0,
|
||||
"disk_info": "1.0 / 1.0 GB",
|
||||
"disk_process": 100.0,
|
||||
"brand_raw": cpuinfo_get_cpu_info["brand_raw"],
|
||||
"baidu": "red",
|
||||
"google": "red",
|
||||
"system": f"{platform_uname.system} " f"{platform_uname.release}",
|
||||
"version": __get_version(),
|
||||
"plugin_count": len(nonebot.get_loaded_plugins()),
|
||||
"nickname": BotConfig.self_nickname,
|
||||
}
|
||||
},
|
||||
pages={
|
||||
"viewport": {"width": 195, "height": 750},
|
||||
"base_url": f"file://{mock_template_path_new.absolute()}",
|
||||
},
|
||||
wait=2,
|
||||
)
|
||||
mock_template_to_pic.assert_awaited_once()
|
||||
mock_build_message.assert_called_once_with(mock_template_to_pic_return)
|
||||
mock_build_message_return.send.assert_awaited_once()
|
||||
|
||||
|
||||
async def test_check_arm(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试自检(arm)
|
||||
"""
|
||||
from zhenxun.configs.config import BotConfig
|
||||
from zhenxun.builtin_plugins.check import _matcher
|
||||
from zhenxun.builtin_plugins.check.data_source import __get_version
|
||||
|
||||
platform_uname_arm = platform.uname_result(
|
||||
system="Linux",
|
||||
node="zhenxun",
|
||||
release="5.15.0-1017-oracle",
|
||||
version="#22~20.04.1-Ubuntu SMP Wed Aug 24 11:13:15 UTC 2022",
|
||||
machine="aarch64",
|
||||
) # type: ignore
|
||||
mock_subprocess_check_output = mocker.patch(
|
||||
"zhenxun.builtin_plugins.check.data_source.subprocess.check_output"
|
||||
)
|
||||
mock_environ_copy = mocker.patch(
|
||||
"zhenxun.builtin_plugins.check.data_source.os.environ.copy"
|
||||
)
|
||||
mock_environ_copy_return = mocker.MagicMock()
|
||||
mock_environ_copy.return_value = mock_environ_copy_return
|
||||
(
|
||||
mock_psutil,
|
||||
mock_cpuinfo,
|
||||
mock_platform,
|
||||
mock_template_to_pic,
|
||||
mock_template_to_pic_return,
|
||||
mock_build_message,
|
||||
mock_build_message_return,
|
||||
mock_template_path_new,
|
||||
) = init_mocker(mocker, tmp_path)
|
||||
|
||||
mock_platform.uname.return_value = platform_uname_arm
|
||||
mock_cpuinfo.get_cpu_info.return_value = {}
|
||||
mock_psutil.cpu_freq.return_value = {}
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = "自检"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID_3,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
mock_template_to_pic.assert_awaited_once_with(
|
||||
template_path=str((mock_template_path_new / "check").absolute()),
|
||||
template_name="main.html",
|
||||
templates={
|
||||
"data": {
|
||||
"cpu_info": "1.0% - 0.0Ghz [1 core]",
|
||||
"cpu_process": 1.0,
|
||||
"ram_info": "1.0 / 1.0 GB",
|
||||
"ram_process": 100.0,
|
||||
"swap_info": "1.0 / 1.0 GB",
|
||||
"swap_process": 100.0,
|
||||
"disk_info": "1.0 / 1.0 GB",
|
||||
"disk_process": 100.0,
|
||||
"brand_raw": "",
|
||||
"baidu": "red",
|
||||
"google": "red",
|
||||
"system": f"{platform_uname_arm.system} "
|
||||
f"{platform_uname_arm.release}",
|
||||
"version": __get_version(),
|
||||
"plugin_count": len(nonebot.get_loaded_plugins()),
|
||||
"nickname": BotConfig.self_nickname,
|
||||
}
|
||||
},
|
||||
pages={
|
||||
"viewport": {"width": 195, "height": 750},
|
||||
"base_url": f"file://{mock_template_path_new.absolute()}",
|
||||
},
|
||||
wait=2,
|
||||
)
|
||||
mock_subprocess_check_output.assert_has_calls(
|
||||
[
|
||||
mocker.call(["lscpu"], env=mock_environ_copy_return),
|
||||
mocker.call().decode(),
|
||||
mocker.call().decode().splitlines(),
|
||||
mocker.call().decode().splitlines().__iter__(),
|
||||
mocker.call(["dmidecode", "-s", "processor-frequency"]),
|
||||
mocker.call().decode(),
|
||||
mocker.call().decode().split(),
|
||||
mocker.call().decode().split().__getitem__(0),
|
||||
mocker.call().decode().split().__getitem__().__float__(),
|
||||
] # type: ignore
|
||||
)
|
||||
mock_template_to_pic.assert_awaited_once()
|
||||
mock_build_message.assert_called_once_with(mock_template_to_pic_return)
|
||||
mock_build_message_return.send.assert_awaited_once()
|
||||
339
tests/builtin_plugins/plugin_store/test_add_plugin.py
Normal file
@ -0,0 +1,339 @@
|
||||
from typing import cast
|
||||
from pathlib import Path
|
||||
from collections.abc import Callable
|
||||
|
||||
import pytest
|
||||
from nonebug import App
|
||||
from respx import MockRouter
|
||||
from pytest_mock import MockerFixture
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from nonebot.adapters.onebot.v11.message import Message
|
||||
from nonebot.adapters.onebot.v11.event import GroupMessageEvent
|
||||
|
||||
from tests.utils import _v11_group_message_event
|
||||
from tests.config import BotId, UserId, GroupId, MessageId
|
||||
from tests.builtin_plugins.plugin_store.utils import init_mocked_api
|
||||
|
||||
|
||||
@pytest.mark.parametrize("package_api", ["jsd", "gh"])
|
||||
async def test_add_plugin_basic(
|
||||
package_api: str,
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试添加基础插件
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
mock_base_path = mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.data_source.BASE_PATH",
|
||||
new=tmp_path / "zhenxun",
|
||||
)
|
||||
|
||||
if package_api != "jsd":
|
||||
mocked_api["zhenxun_bot_plugins_metadata"].respond(404)
|
||||
if package_api != "gh":
|
||||
mocked_api["zhenxun_bot_plugins_tree"].respond(404)
|
||||
|
||||
plugin_id = 1
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"添加插件 {plugin_id}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message=f"正在添加插件 Id: {plugin_id}"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message="插件 识图 安装成功! 重启后生效"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
assert mocked_api["search_image_plugin_file_init"].called
|
||||
assert (mock_base_path / "plugins" / "search_image" / "__init__.py").is_file()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("package_api", ["jsd", "gh"])
|
||||
async def test_add_plugin_basic_commit_version(
|
||||
package_api: str,
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试添加基础插件
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
mock_base_path = mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.data_source.BASE_PATH",
|
||||
new=tmp_path / "zhenxun",
|
||||
)
|
||||
|
||||
if package_api != "jsd":
|
||||
mocked_api["zhenxun_bot_plugins_metadata_commit"].respond(404)
|
||||
if package_api != "gh":
|
||||
mocked_api["zhenxun_bot_plugins_tree_commit"].respond(404)
|
||||
|
||||
plugin_id = 3
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"添加插件 {plugin_id}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message=f"正在添加插件 Id: {plugin_id}"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message="插件 B站订阅 安装成功! 重启后生效"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
if package_api == "jsd":
|
||||
assert mocked_api["zhenxun_bot_plugins_metadata_commit"].called
|
||||
if package_api == "gh":
|
||||
assert mocked_api["zhenxun_bot_plugins_tree_commit"].called
|
||||
assert mocked_api["bilibili_sub_plugin_file_init"].called
|
||||
assert (mock_base_path / "plugins" / "bilibili_sub" / "__init__.py").is_file()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("package_api", ["jsd", "gh"])
|
||||
async def test_add_plugin_basic_is_not_dir(
|
||||
package_api: str,
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试添加基础插件,插件不是目录
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
mock_base_path = mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.data_source.BASE_PATH",
|
||||
new=tmp_path / "zhenxun",
|
||||
)
|
||||
|
||||
if package_api != "jsd":
|
||||
mocked_api["zhenxun_bot_plugins_metadata"].respond(404)
|
||||
if package_api != "gh":
|
||||
mocked_api["zhenxun_bot_plugins_tree"].respond(404)
|
||||
|
||||
plugin_id = 0
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"添加插件 {plugin_id}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message=f"正在添加插件 Id: {plugin_id}"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message="插件 鸡汤 安装成功! 重启后生效"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
assert mocked_api["jitang_plugin_file"].called
|
||||
assert (mock_base_path / "plugins" / "alapi" / "jitang.py").is_file()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("package_api", ["jsd", "gh"])
|
||||
async def test_add_plugin_extra(
|
||||
package_api: str,
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试添加额外插件
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
mock_base_path = mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.data_source.BASE_PATH",
|
||||
new=tmp_path / "zhenxun",
|
||||
)
|
||||
|
||||
if package_api != "jsd":
|
||||
mocked_api["zhenxun_github_sub_metadata"].respond(404)
|
||||
if package_api != "gh":
|
||||
mocked_api["zhenxun_github_sub_tree"].respond(404)
|
||||
|
||||
plugin_id = 4
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message: str = f"添加插件 {plugin_id}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message=f"正在添加插件 Id: {plugin_id}"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message="插件 github订阅 安装成功! 重启后生效"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
assert mocked_api["github_sub_plugin_file_init"].called
|
||||
assert (mock_base_path / "plugins" / "github_sub" / "__init__.py").is_file()
|
||||
|
||||
|
||||
async def test_plugin_not_exist_add(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试插件不存在,添加插件
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
plugin_id = -1
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"添加插件 {plugin_id}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message=f"正在添加插件 Id: {plugin_id}"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message="插件ID不存在..."),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
|
||||
|
||||
async def test_add_plugin_exist(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试插件已经存在,添加插件
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.data_source.ShopManage.get_loaded_plugins",
|
||||
return_value=[("search_image", "0.1")],
|
||||
)
|
||||
plugin_id = 1
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"添加插件 {plugin_id}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message=f"正在添加插件 Id: {plugin_id}"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message="插件 识图 已安装,无需重复安装"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
140
tests/builtin_plugins/plugin_store/test_plugin_store.py
Normal file
@ -0,0 +1,140 @@
|
||||
from typing import cast
|
||||
from pathlib import Path
|
||||
from collections.abc import Callable
|
||||
|
||||
from nonebug import App
|
||||
from respx import MockRouter
|
||||
from pytest_mock import MockerFixture
|
||||
from nonebot.adapters.onebot.v11 import Bot, Message
|
||||
from nonebot.adapters.onebot.v11.event import GroupMessageEvent
|
||||
|
||||
from tests.utils import _v11_group_message_event
|
||||
from tests.config import BotId, UserId, GroupId, MessageId
|
||||
from tests.builtin_plugins.plugin_store.utils import init_mocked_api
|
||||
|
||||
|
||||
async def test_plugin_store(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试插件商店
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
from zhenxun.builtin_plugins.plugin_store.data_source import row_style
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
|
||||
mock_table_page = mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.data_source.ImageTemplate.table_page"
|
||||
)
|
||||
mock_table_page_return = mocker.AsyncMock()
|
||||
mock_table_page.return_value = mock_table_page_return
|
||||
|
||||
mock_build_message = mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.MessageUtils.build_message"
|
||||
)
|
||||
mock_build_message_return = mocker.AsyncMock()
|
||||
mock_build_message.return_value = mock_build_message_return
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = "插件商店"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID_3,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
mock_table_page.assert_awaited_once_with(
|
||||
"插件列表",
|
||||
"通过添加/移除插件 ID 来管理插件",
|
||||
["-", "ID", "名称", "简介", "作者", "版本", "类型"],
|
||||
[
|
||||
["", 0, "鸡汤", "喏,亲手为你煮的鸡汤", "HibiKier", "0.1", "普通插件"],
|
||||
["", 1, "识图", "以图搜图,看破本源", "HibiKier", "0.1", "普通插件"],
|
||||
["", 2, "网易云热评", "生了个人,我很抱歉", "HibiKier", "0.1", "普通插件"],
|
||||
[
|
||||
"",
|
||||
3,
|
||||
"B站订阅",
|
||||
"非常便利的B站订阅通知",
|
||||
"HibiKier",
|
||||
"0.3-b101fbc",
|
||||
"普通插件",
|
||||
],
|
||||
[
|
||||
"",
|
||||
4,
|
||||
"github订阅",
|
||||
"订阅github用户或仓库",
|
||||
"xuanerwa",
|
||||
"0.7",
|
||||
"普通插件",
|
||||
],
|
||||
[
|
||||
"",
|
||||
5,
|
||||
"Minecraft查服",
|
||||
"Minecraft服务器状态查询,支持IPv6",
|
||||
"molanp",
|
||||
"1.13",
|
||||
"普通插件",
|
||||
],
|
||||
],
|
||||
text_style=row_style,
|
||||
)
|
||||
mock_build_message.assert_called_once_with(mock_table_page_return)
|
||||
mock_build_message_return.send.assert_awaited_once()
|
||||
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
|
||||
|
||||
async def test_plugin_store_fail(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试插件商店
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
mocked_api.get(
|
||||
"https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins/main/plugins.json",
|
||||
name="basic_plugins",
|
||||
).respond(404)
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = "插件商店"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID_3,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message("获取插件列表失败..."),
|
||||
result=None,
|
||||
exception=None,
|
||||
bot=bot,
|
||||
)
|
||||
|
||||
assert mocked_api["basic_plugins"].called
|
||||
142
tests/builtin_plugins/plugin_store/test_remove_plugin.py
Normal file
@ -0,0 +1,142 @@
|
||||
# ruff: noqa: ASYNC230
|
||||
|
||||
from typing import cast
|
||||
from pathlib import Path
|
||||
from collections.abc import Callable
|
||||
|
||||
from nonebug import App
|
||||
from respx import MockRouter
|
||||
from pytest_mock import MockerFixture
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from nonebot.adapters.onebot.v11.message import Message
|
||||
from nonebot.adapters.onebot.v11.event import GroupMessageEvent
|
||||
|
||||
from tests.utils import _v11_group_message_event
|
||||
from tests.config import BotId, UserId, GroupId, MessageId
|
||||
from tests.builtin_plugins.plugin_store.utils import init_mocked_api, get_content_bytes
|
||||
|
||||
|
||||
async def test_remove_plugin(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试删除插件
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
mock_base_path = mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.data_source.BASE_PATH",
|
||||
new=tmp_path / "zhenxun",
|
||||
)
|
||||
|
||||
plugin_path = mock_base_path / "plugins" / "search_image"
|
||||
plugin_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with open(plugin_path / "__init__.py", "wb") as f:
|
||||
f.write(get_content_bytes("search_image.py"))
|
||||
|
||||
plugin_id = 1
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"移除插件 {plugin_id}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message="插件 识图 移除成功! 重启后生效"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
assert not (mock_base_path / "plugins" / "search_image" / "__init__.py").is_file()
|
||||
|
||||
|
||||
async def test_plugin_not_exist_remove(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试插件不存在,移除插件
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
plugin_id = -1
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"移除插件 {plugin_id}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID_2,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message="插件ID不存在..."),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
|
||||
|
||||
async def test_remove_plugin_not_install(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试插件未安装,移除插件
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
_ = mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.data_source.BASE_PATH",
|
||||
new=tmp_path / "zhenxun",
|
||||
)
|
||||
plugin_id = 1
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"移除插件 {plugin_id}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID_2,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message="插件 识图 不存在..."),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
182
tests/builtin_plugins/plugin_store/test_search_plugin.py
Normal file
@ -0,0 +1,182 @@
|
||||
from typing import cast
|
||||
from pathlib import Path
|
||||
from collections.abc import Callable
|
||||
|
||||
from nonebug import App
|
||||
from respx import MockRouter
|
||||
from pytest_mock import MockerFixture
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from nonebot.adapters.onebot.v11.message import Message
|
||||
from nonebot.adapters.onebot.v11.event import GroupMessageEvent
|
||||
|
||||
from tests.utils import _v11_group_message_event
|
||||
from tests.config import BotId, UserId, GroupId, MessageId
|
||||
from tests.builtin_plugins.plugin_store.utils import init_mocked_api
|
||||
|
||||
|
||||
async def test_search_plugin_name(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试搜索插件
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
from zhenxun.builtin_plugins.plugin_store.data_source import row_style
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
|
||||
mock_table_page = mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.data_source.ImageTemplate.table_page"
|
||||
)
|
||||
mock_table_page_return = mocker.AsyncMock()
|
||||
mock_table_page.return_value = mock_table_page_return
|
||||
|
||||
mock_build_message = mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.MessageUtils.build_message"
|
||||
)
|
||||
mock_build_message_return = mocker.AsyncMock()
|
||||
mock_build_message.return_value = mock_build_message_return
|
||||
|
||||
plugin_name = "github订阅"
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"搜索插件 {plugin_name}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID_3,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
mock_table_page.assert_awaited_once_with(
|
||||
"插件列表",
|
||||
"通过添加/移除插件 ID 来管理插件",
|
||||
["-", "ID", "名称", "简介", "作者", "版本", "类型"],
|
||||
[
|
||||
[
|
||||
"",
|
||||
4,
|
||||
"github订阅",
|
||||
"订阅github用户或仓库",
|
||||
"xuanerwa",
|
||||
"0.7",
|
||||
"普通插件",
|
||||
]
|
||||
],
|
||||
text_style=row_style,
|
||||
)
|
||||
mock_build_message.assert_called_once_with(mock_table_page_return)
|
||||
mock_build_message_return.send.assert_awaited_once()
|
||||
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
|
||||
|
||||
async def test_search_plugin_author(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试搜索插件,作者
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
from zhenxun.builtin_plugins.plugin_store.data_source import row_style
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
|
||||
mock_table_page = mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.data_source.ImageTemplate.table_page"
|
||||
)
|
||||
mock_table_page_return = mocker.AsyncMock()
|
||||
mock_table_page.return_value = mock_table_page_return
|
||||
|
||||
mock_build_message = mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.MessageUtils.build_message"
|
||||
)
|
||||
mock_build_message_return = mocker.AsyncMock()
|
||||
mock_build_message.return_value = mock_build_message_return
|
||||
|
||||
author_name = "xuanerwa"
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"搜索插件 {author_name}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID_3,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
mock_table_page.assert_awaited_once_with(
|
||||
"插件列表",
|
||||
"通过添加/移除插件 ID 来管理插件",
|
||||
["-", "ID", "名称", "简介", "作者", "版本", "类型"],
|
||||
[
|
||||
[
|
||||
"",
|
||||
4,
|
||||
"github订阅",
|
||||
"订阅github用户或仓库",
|
||||
"xuanerwa",
|
||||
"0.7",
|
||||
"普通插件",
|
||||
]
|
||||
],
|
||||
text_style=row_style,
|
||||
)
|
||||
mock_build_message.assert_called_once_with(mock_table_page_return)
|
||||
mock_build_message_return.send.assert_awaited_once()
|
||||
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
|
||||
|
||||
async def test_plugin_not_exist_search(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试插件不存在,搜索插件
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
plugin_name = "not_exist_plugin_name"
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"搜索插件 {plugin_name}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID_3,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message="未找到相关插件..."),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
206
tests/builtin_plugins/plugin_store/test_update_plugin.py
Normal file
@ -0,0 +1,206 @@
|
||||
from typing import cast
|
||||
from pathlib import Path
|
||||
from collections.abc import Callable
|
||||
|
||||
from nonebug import App
|
||||
from respx import MockRouter
|
||||
from pytest_mock import MockerFixture
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from nonebot.adapters.onebot.v11.message import Message
|
||||
from nonebot.adapters.onebot.v11.event import GroupMessageEvent
|
||||
|
||||
from tests.utils import _v11_group_message_event
|
||||
from tests.config import BotId, UserId, GroupId, MessageId
|
||||
from tests.builtin_plugins.plugin_store.utils import init_mocked_api
|
||||
|
||||
|
||||
async def test_update_plugin_basic_need_update(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试更新基础插件,插件需要更新
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
mock_base_path = mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.data_source.BASE_PATH",
|
||||
new=tmp_path / "zhenxun",
|
||||
)
|
||||
mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.data_source.ShopManage.get_loaded_plugins",
|
||||
return_value=[("search_image", "0.0")],
|
||||
)
|
||||
|
||||
plugin_id = 1
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"更新插件 {plugin_id}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message=f"正在更新插件 Id: {plugin_id}"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message="插件 识图 更新成功! 重启后生效"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
assert mocked_api["search_image_plugin_file_init"].called
|
||||
assert (mock_base_path / "plugins" / "search_image" / "__init__.py").is_file()
|
||||
|
||||
|
||||
async def test_update_plugin_basic_is_new(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试更新基础插件,插件是最新版
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.data_source.BASE_PATH",
|
||||
new=tmp_path / "zhenxun",
|
||||
)
|
||||
mocker.patch(
|
||||
"zhenxun.builtin_plugins.plugin_store.data_source.ShopManage.get_loaded_plugins",
|
||||
return_value=[("search_image", "0.1")],
|
||||
)
|
||||
|
||||
plugin_id = 1
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"更新插件 {plugin_id}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message=f"正在更新插件 Id: {plugin_id}"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message="插件 识图 已是最新版本"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
|
||||
|
||||
async def test_plugin_not_exist_update(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试插件不存在,更新插件
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
plugin_id = -1
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"更新插件 {plugin_id}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID_2,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message=f"正在更新插件 Id: {plugin_id}"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message="插件ID不存在..."),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
|
||||
|
||||
async def test_update_plugin_not_install(
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
create_bot: Callable,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
测试插件不存在,更新插件
|
||||
"""
|
||||
from zhenxun.builtin_plugins.plugin_store import _matcher
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
plugin_id = 1
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
bot = create_bot(ctx)
|
||||
bot: Bot = cast(Bot, bot)
|
||||
raw_message = f"更新插件 {plugin_id}"
|
||||
event: GroupMessageEvent = _v11_group_message_event(
|
||||
message=raw_message,
|
||||
self_id=BotId.QQ_BOT,
|
||||
user_id=UserId.SUPERUSER,
|
||||
group_id=GroupId.GROUP_ID_LEVEL_5,
|
||||
message_id=MessageId.MESSAGE_ID_2,
|
||||
to_me=True,
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message=f"正在更新插件 Id: {plugin_id}"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
ctx.should_call_send(
|
||||
event=event,
|
||||
message=Message(message="插件 识图 未安装,无法更新"),
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||