diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index 2f45635..0000000
--- a/.dockerignore
+++ /dev/null
@@ -1,473 +0,0 @@
-# ----- Project -----
-
-# .env.*
-.dockerignore
-Dockerfile
-docker-compose.yml
-README.md
-
-# Created by https://www.toptal.com/developers/gitignore/api/python,node,visualstudiocode,jetbrains,macos,windows,linux
-# Edit at https://www.toptal.com/developers/gitignore?templates=python,node,visualstudiocode,jetbrains,macos,windows,linux
-
-### JetBrains ###
-# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
-# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
-
-# User-specific stuff
-.idea/**/workspace.xml
-.idea/**/tasks.xml
-.idea/**/usage.statistics.xml
-.idea/**/dictionaries
-.idea/**/shelf
-
-# AWS User-specific
-.idea/**/aws.xml
-
-# Generated files
-.idea/**/contentModel.xml
-
-# Sensitive or high-churn files
-.idea/**/dataSources/
-.idea/**/dataSources.ids
-.idea/**/dataSources.local.xml
-.idea/**/sqlDataSources.xml
-.idea/**/dynamic.xml
-.idea/**/uiDesigner.xml
-.idea/**/dbnavigator.xml
-
-# Gradle
-.idea/**/gradle.xml
-.idea/**/libraries
-
-# Gradle and Maven with auto-import
-# When using Gradle or Maven with auto-import, you should exclude module files,
-# since they will be recreated, and may cause churn. Uncomment if using
-# auto-import.
-# .idea/artifacts
-# .idea/compiler.xml
-# .idea/jarRepositories.xml
-# .idea/modules.xml
-# .idea/*.iml
-# .idea/modules
-# *.iml
-# *.ipr
-
-# CMake
-cmake-build-*/
-
-# Mongo Explorer plugin
-.idea/**/mongoSettings.xml
-
-# File-based project format
-*.iws
-
-# IntelliJ
-out/
-
-# mpeltonen/sbt-idea plugin
-.idea_modules/
-
-# JIRA plugin
-atlassian-ide-plugin.xml
-
-# Cursive Clojure plugin
-.idea/replstate.xml
-
-# Crashlytics plugin (for Android Studio and IntelliJ)
-com_crashlytics_export_strings.xml
-crashlytics.properties
-crashlytics-build.properties
-fabric.properties
-
-# Editor-based Rest Client
-.idea/httpRequests
-
-# Android studio 3.1+ serialized cache file
-.idea/caches/build_file_checksums.ser
-
-### JetBrains Patch ###
-# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
-
-# *.iml
-# modules.xml
-# .idea/misc.xml
-# *.ipr
-
-# Sonarlint plugin
-# https://plugins.jetbrains.com/plugin/7973-sonarlint
-.idea/**/sonarlint/
-
-# SonarQube Plugin
-# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
-.idea/**/sonarIssues.xml
-
-# Markdown Navigator plugin
-# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
-.idea/**/markdown-navigator.xml
-.idea/**/markdown-navigator-enh.xml
-.idea/**/markdown-navigator/
-
-# Cache file creation bug
-# See https://youtrack.jetbrains.com/issue/JBR-2257
-.idea/$CACHE_FILE$
-
-# CodeStream plugin
-# https://plugins.jetbrains.com/plugin/12206-codestream
-.idea/codestream.xml
-
-### Linux ###
-*~
-
-# temporary files which can be created if a process still has a handle open of a deleted file
-.fuse_hidden*
-
-# KDE directory preferences
-.directory
-
-# Linux trash folder which might appear on any partition or disk
-.Trash-*
-
-# .nfs files are created when an open file is removed but is still being accessed
-.nfs*
-
-### macOS ###
-# General
-.DS_Store
-.AppleDouble
-.LSOverride
-
-# Icon must end with two \r
-Icon
-
-# Thumbnails
-._*
-
-# Files that might appear in the root of a volume
-.DocumentRevisions-V100
-.fseventsd
-.Spotlight-V100
-.TemporaryItems
-.Trashes
-.VolumeIcon.icns
-.com.apple.timemachine.donotpresent
-
-# Directories potentially created on remote AFP share
-.AppleDB
-.AppleDesktop
-Network Trash Folder
-Temporary Items
-.apdisk
-
-### Node ###
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-lerna-debug.log*
-.pnpm-debug.log*
-
-# Diagnostic reports (https://nodejs.org/api/report.html)
-report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-*.lcov
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
-
-# Snowpack dependency directory (https://snowpack.dev/)
-web_modules/
-
-# TypeScript cache
-*.tsbuildinfo
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Microbundle cache
-.rpt2_cache/
-.rts2_cache_cjs/
-.rts2_cache_es/
-.rts2_cache_umd/
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variables file
-# .env
-.env.test
-.env.production
-
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-.parcel-cache
-
-# Next.js build output
-.next
-out
-
-# Nuxt.js build / generate output
-.nuxt
-dist
-
-# Gatsby files
-.cache/
-# Comment in the public line in if your project uses Gatsby and not Next.js
-# https://nextjs.org/blog/next-9-1#public-directory-support
-# public
-
-# vuepress build output
-.vuepress/dist
-
-# Serverless directories
-.serverless/
-
-# FuseBox cache
-.fusebox/
-
-# DynamoDB Local files
-.dynamodb/
-
-# TernJS port file
-.tern-port
-
-# Stores VSCode versions used for testing VSCode extensions
-.vscode-test
-
-# yarn v2
-.yarn/cache
-.yarn/unplugged
-.yarn/build-state.yml
-.yarn/install-state.gz
-.pnp.*
-
-### Node Patch ###
-# Serverless Webpack directories
-.webpack/
-
-# Optional stylelint cache
-.stylelintcache
-
-# SvelteKit build / generate output
-.svelte-kit
-
-### Python ###
-# Byte-compiled / optimized / DLL files
-__pycache__/
-*.py[cod]
-*$py.class
-
-# C extensions
-*.so
-
-# Distribution / packaging
-.Python
-build/
-develop-eggs/
-dist/
-downloads/
-eggs/
-.eggs/
-lib/
-lib64/
-parts/
-sdist/
-var/
-wheels/
-share/python-wheels/
-*.egg-info/
-.installed.cfg
-*.egg
-MANIFEST
-
-# PyInstaller
-# Usually these files are written by a python script from a template
-# before PyInstaller builds the exe, so as to inject date/other infos into it.
-*.manifest
-*.spec
-
-# Installer logs
-pip-log.txt
-pip-delete-this-directory.txt
-
-# Unit test / coverage reports
-htmlcov/
-.tox/
-.nox/
-.coverage
-.coverage.*
-nosetests.xml
-coverage.xml
-*.cover
-*.py,cover
-.hypothesis/
-.pytest_cache/
-cover/
-
-# Translations
-*.mo
-*.pot
-
-# Django stuff:
-local_settings.py
-db.sqlite3
-db.sqlite3-journal
-
-# Flask stuff:
-instance/
-.webassets-cache
-
-# Scrapy stuff:
-.scrapy
-
-# Sphinx documentation
-docs/_build/
-
-# PyBuilder
-.pybuilder/
-target/
-
-# Jupyter Notebook
-.ipynb_checkpoints
-
-# IPython
-profile_default/
-ipython_config.py
-
-# pyenv
-# For a library or package, you might want to ignore these files since the code is
-# intended to run in multiple environments; otherwise, check them in:
-# .python-version
-
-# pipenv
-# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
-# However, in case of collaboration, if having platform-specific dependencies or dependencies
-# having no cross-platform support, pipenv may install dependencies that don't work, or not
-# install all needed dependencies.
-#Pipfile.lock
-
-# PEP 582; used by e.g. github.com/David-OConnor/pyflow
-__pypackages__/
-
-# Celery stuff
-celerybeat-schedule
-celerybeat.pid
-
-# SageMath parsed files
-*.sage.py
-
-# Environments
-.venv
-env/
-venv/
-ENV/
-env.bak/
-venv.bak/
-
-# Spyder project settings
-.spyderproject
-.spyproject
-
-# Rope project settings
-.ropeproject
-
-# mkdocs documentation
-/site
-
-# mypy
-.mypy_cache/
-.dmypy.json
-dmypy.json
-
-# Pyre type checker
-.pyre/
-
-# pytype static type analyzer
-.pytype/
-
-# Cython debug symbols
-cython_debug/
-
-### VisualStudioCode ###
-.vscode/*
-# !.vscode/settings.json
-# !.vscode/tasks.json
-# !.vscode/launch.json
-# !.vscode/extensions.json
-*.code-workspace
-
-# Local History for Visual Studio Code
-.history/
-
-### VisualStudioCode Patch ###
-# Ignore all local history of files
-.history
-.ionide
-
-# Support for Project snippet scope
-!.vscode/*.code-snippets
-
-### Windows ###
-# Windows thumbnail cache files
-Thumbs.db
-Thumbs.db:encryptable
-ehthumbs.db
-ehthumbs_vista.db
-
-# Dump file
-*.stackdump
-
-# Folder config file
-[Dd]esktop.ini
-
-# Recycle Bin used on file shares
-$RECYCLE.BIN/
-
-# Windows Installer files
-*.cab
-*.msi
-*.msix
-*.msm
-*.msp
-
-# Windows shortcuts
-*.lnk
-
-# End of https://www.toptal.com/developers/gitignore/api/python,node,visualstudiocode,jetbrains,macos,windows,linux
diff --git a/.github/ISSUE_TEMPLATE/issue-template-question.md b/.github/ISSUE_TEMPLATE/issue-template-question.md
new file mode 100644
index 0000000..490d145
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/issue-template-question.md
@@ -0,0 +1,32 @@
+---
+name: 🐛 问题报告或求助
+about: 在使用中遇到问题,希望得到帮助
+title: '[问题]标题'
+labels: question
+assignees: ''
+
+---
+
+### 确认
+
+- 我的Bot版本已更新到最新,且已尝试使用`nb paimon install`更新依赖库
+- 我已查阅[文档](https://blog.angforever.top/2023/01/06/ANGANGBOT1/),无相关解决方案
+- 我已确认[issue](https://github.com/ANGJustinl/ANGANGBOT/issues)中没有类似的问题或仍然得不到解决
+
+### 环境信息
+
+- 系统版本: Windows10(example)
+- Python版本: 3.10.0(example)
+- Nonebot2版本: 2.1.0(example)
+
+### 问题描述
+
+简单的描述问题发生过程或表现...
+
+### 问题截图
+
+提供问题或日志截图...
+
+### 复现步骤[可选]
+
+描述问题复现过程...
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/issue-template-suggestion.md b/.github/ISSUE_TEMPLATE/issue-template-suggestion.md
new file mode 100644
index 0000000..6df1fd1
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/issue-template-suggestion.md
@@ -0,0 +1,24 @@
+---
+name: ✨ 功能需求或建议
+about: 为项目提出一个新的想法或建议
+title: '[建议]标题'
+labels: enhancement
+assignees: ''
+
+---
+
+### 当前不足
+
+简单描述本项目当前存在的不足之处...
+
+### 建议内容
+
+描述你想要的功能或建议...
+
+- 建议一
+- 建议二
+- ...
+
+### 参考示例[可选]
+
+是否有其他项目或者工具有类似的功能,可提供链接或截图...
\ No newline at end of file
diff --git a/.github/release.yml b/.github/release.yml
new file mode 100644
index 0000000..3b00d19
--- /dev/null
+++ b/.github/release.yml
@@ -0,0 +1,21 @@
+changelog:
+ categories:
+ - title: 💥 破坏性更新
+ labels:
+ - Semver-Major
+ - breaking-change
+ - title: ✨ 新特性
+ labels:
+ - enhancement
+ - title: 🐛 BUG修复
+ labels:
+ - bug
+ - title: 📝 文档更新
+ labels:
+ - documentation
+ - title: 💫 杂项
+ labels:
+ - "*"
+ exclude:
+ labels:
+ - dependencies
\ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 48fe897..1bfdbd6 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -3,7 +3,7 @@ name: Docker Hub Release
on:
push:
tags:
- - "v*"
+ - "v**"
jobs:
docker:
diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml
new file mode 100644
index 0000000..3cb0cbd
--- /dev/null
+++ b/.github/workflows/dependencies.yml
@@ -0,0 +1,40 @@
+name: Update Dependencies
+
+on:
+ push:
+ paths:
+ - 'poetry.lock'
+ - 'pyproject.toml'
+ workflow_dispatch:
+
+jobs:
+ UpdateDependencies:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout source
+ uses: actions/checkout@master
+
+ - name: Set up Python
+ uses: actions/setup-python@v2
+ with:
+ python-version: 3.10
+
+ - name: Set up Poetry
+ uses: Gr1N/setup-poetry@v8
+
+ - name: lock poetry.lock
+ run: poetry lock
+
+ - name: export requirements.txt
+ run: poetry export --without-hashes -f requirements.txt --output requirements.txt
+
+ - name: Commit changes
+ uses: EndBug/add-and-commit@v9
+ with:
+ author_name: github-actions[bot]
+ author_email: github-actions[bot]@users.noreply.github.com
+ message: ':wrench: 自动更新依赖文件'
+ add: |
+ 'poetry.lock'
+ 'requirements.txt'
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 4a91f66..0bee633 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,14 +1,14 @@
# ANGANGBOT #
-/data
-/docker
-/cache
+data
+docker
+cache
*.log
*.png
*.gif
.env.dev
-.env.prod
+set.json
setu_perm_cfg.json
-dev.*.py
+.idea
# Byte-compiled / optimized / DLL files
__pycache__/
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 0c32d51..f8ee303 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -7,16 +7,11 @@ ci:
autoupdate_commit_msg: ":arrow_up: auto update by pre-commit hooks"
repos:
- repo: https://github.com/psf/black
- rev: 23.3.0
+ rev: 24.2.0
hooks:
- id: black
stages: [commit]
- - repo: https://github.com/pycqa/isort
- rev: 5.10.1
- hooks:
- - id: isort
- args: ["--profile", "black", "--filter-files"]
- repo: https://github.com/nonebot/nonemoji
rev: v0.1.4
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 69954f6..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,34 +0,0 @@
-FROM python:3.10 as requirements_stage
-
-WORKDIR /wheel
-
-RUN python -m pip install --user pipx
-
-COPY ./pyproject.toml \
- /wheel/
-
-
-
-RUN python -m pipx run --no-cache nb-cli generate -f /tmp/bot.py
-
-
-FROM python:3.10-slim
-
-WORKDIR /app
-
-ENV TZ Asia/Shanghai
-ENV PYTHONPATH=/app
-
-COPY ./docker/gunicorn_conf.py ./docker/start.sh /
-RUN chmod +x /start.sh
-
-ENV APP_MODULE _main:app
-ENV MAX_WORKERS 1
-
-COPY --from=requirements_stage /tmp/bot.py /app
-COPY ./docker/_main.py /app
-
-RUN pip install --no-cache-dir gunicorn uvicorn[standard] nonebot2
-COPY . /app/
-
-CMD ["/start.sh"]
\ No newline at end of file
diff --git a/README.md b/README.md
index 187587c..5f2bb31 100644
--- a/README.md
+++ b/README.md
@@ -28,6 +28,9 @@
一切开发旨在学习,请勿用于非法用途
+# 旧版文档请见 https://github.com/ANGJustinl/ANGANGBOT/README.md (v2以前)
+
+
## | 🚀部署 (可参照 https://angjustinl.github.io/2023/01/06/ANGANGBOT1/ )
---
@@ -38,37 +41,21 @@
---
-至少需要Python3.9及以上版本(推荐3.10),可通过python -V或python3 -V查看版本号
+至少需要Python3.8及以上版本(推荐3.10),可通过python -V或python3 -V查看版本号
此 README 提供了最低程度的基于 nonebot 进行安装的教程与支持。
建议您至少拥有一定的编程基础之后再尝试使用本工具。
-1. 安装 Python
-
-2. 前往 https://github.com/ANGJustinl/ANGANGBOT/releases 下载lite文件并解压至本地
-
-3. 下载需要的资源文件
-
- >部分插件需额外下载src文件夹进行替换
- >
- >资源文件仅供学习交流使用,请自觉在下载 24 小时内删除资源文件。
- >
- >在运行代码之前,您需要从此链接 https://cowtransfer.com/s/c7fa24d11b3949 [传输口令 rt318w]
- >
- >下载资源文件并解压到src文件夹中
-
-4. 安装依赖
+1. 安装 Python (推荐>=3.9)
+2. 前往 https://github.com/ANGJustinl/ANGANGBOT/releases 下载
+3. 安装依赖
-推荐使用powershell + nb-cil脚手架
+推荐使用nb-cil脚手架 `pip install nb-cli` + 在项目的根目录(即 bot.py 文件所在的位置)按下 Shift + 右键,点击【在此处打开 CMD/PowerShell 窗口】 后
-Ⅰ. ```pip install nb-cli```
+```pip install -r requirements.txt```
-Ⅱ.在项目的根目录(即 bot.py 文件所在的位置)按下 Shift + 右键,点击【在此处打开 PowerShell 窗口】
-
-Ⅲ. ```pip install -r requirements.txt```
-
-3.1 修改[.env.prod]配置文件
+3.1 修改 .env.prod 配置文件
```HOST=127.0.0.1 # Nonebot监听的IP-----1
PORT=10219 # Nonebot监听的端口-----2
@@ -85,75 +72,58 @@ COMMAND_SEP=[" "] # 命令分隔符-----7
```
3.2 修改[.env]配置文件
-pixiv功能
+[pixiv功能](https://github.com/bot-ssttkkl/nonebot-plugin-pixivbot#%E9%85%8D%E7%BD%AE%E9%A1%B9%E4%B8%80%E8%A7%88)
+
5 ```pixiv_refresh_token = ''``` 写入你p站的refresh_token,具体获取方法自行百度
-apex功能
-27 ``` apex_api_key = "" ``` https://portal.apexlegendsapi.com/ 获取token
+
+[setu功能 配置](https://github.com/Special-Week/nonebot_plugin_setu4#env-%E9%85%8D%E7%BD%AE%E9%A1%B9)<- 点我
-腾讯云人像变化
-30 `Secret_Id = ""`
-31 ```Secret_Key = ""```
+[运势插件](https://github.com/MinatoAquaCrews/nonebot_plugin_fortune#%E5%91%BD%E4%BB%A4)<- 点我
+
|可选填写部分
|详见[.env]配置文件内容
-4. 启动bot
-
->部分插件需额外下载src文件夹进行替换
->
->资源文件仅供学习交流使用,请自觉在下载 24 小时内删除资源文件。
->
->在运行代码之前,您需要从此链接 https://cowtransfer.com/s/c7fa24d11b3949 [传输口令 rt318w]
->
->下载资源文件并解压到src文件夹中
+1. 启动bot
-推荐使用powershell + nb-cil脚手架
+使用nb-cil脚手架
-Ⅰ.您可以直接在项目的根目录(即 bot.py 文件所在的位置)按下 Shift + 右键,点击【在此处打开 PowerShell 窗口】
-Ⅱ.
-
-nb run
+Ⅰ.您可以直接在项目的根目录 打开 PowerShell 窗口 输入 `nb run`
运行项目。如果输出如下所示的内容,代表运行成功:(由于第一次安装不加载配置文件,或许会略有不同,不报错就是没问题的)
> 10-20 16:40:30 [SUCCESS] nonebot | NoneBot is initializing...
>
-> 10-20 16:40:30 [INFO] nonebot | Current Env: prod
->
-> 10-20 16:40:31 [SUCCESS] nonebot | Succeeded to import "nonebot_plugin_weather_lite"
->
-> ......(这里是被加载的插件)
+> 10-20 16:40:31 [SUCCESS] nonebot | Succeeded to import "example1"(这里是被加载的插件)
>
> 10-20 16:40:32 [SUCCESS] nonebot | Running NoneBot...
>
-> 10-20 16:40:32 [INFO] uvicorn | Started server process [16676]
+> 10-20 16:40:32 [INFO] uvicorn | Started server process [uid]
>
> 10-20 16:40:32 [INFO] uvicorn | Waiting for application startup.
>
> 10-20 16:40:32 [INFO] uvicorn | Application startup complete.
>
-> 10-20 16:40:32 [INFO] uvicorn | Uvicorn running on http://127.0.0.1:10219 (Press CTRL+C to quit)
+> 10-20 16:40:32 [INFO] uvicorn | Uvicorn running on http://ip:port (Press CTRL+C to quit)
-5. 连接 CQ-HTTP
+1. 连接 CQ-HTTP [可自行搜索现版本使用方法 如https://www.bilibili.com/read/cv25444623/]
前往 https://github.com/Mrs4s/go-cqhttp > Releases,下载适合自己操作系统的可执行文件。 go-cqhttp 在初次启动时会询问代理方式,选择反向 websocket 代理即可。之后用任何文本编辑器打开config.yml文件,设置反向 ws 地址、上报方式:
-```message:
- post-format: array
-
+```
servers:
- ws-reverse:
- universal: ws://127.0.0.1:10219/onebot/v11/ws
+ universal: ws://ip:port/onebot/v11/ws
```
然后设置您的 QQ 号和密码。您也可以不设置密码,选择扫码登陆的方式。
登陆成功后,后台应该会发送一条类似的信息:
-> 10-20 16:40:32 [INFO] nonebot | WebSocket Connection from CQHTTP Bot 114514 Accepted!
+> 10-20 16:40:32 [INFO] nonebot | WebSocket Connection from CQHTTP Bot Accepted!
至此,您可以和对应的 QQ 号聊天并使用 angangbot 的基础功能了。
@@ -163,43 +133,23 @@ servers:
对应插件的功能可以自己查询对应插件有关安装方法,此处先不予整合
-
-## | 插件:
-nonebot-plugin-status:https://github.com/cscs181/QQ-GitHub-Bot/tree/master/src/plugins/nonebot_plugin_status
-
-nonebot_plugin_setu4:https://github.com/Special-Week/nonebot_plugin_setu4
-
-nonebot_plugin_weather_lite:https://github.com/zjkwdy/nonebot_plugin_weather_lite
-
-Nonebot Plugin Hammer Nbnhhsh:https://github.com/ArgonarioD/nonebot-plugin-hammer-nbnhhsh
-
-nonebot_plugin_fortune:https://github.com/MinatoAquaCrews/nonebot_plugin_fortune
-
-...... 目前文档任有不全,具体插件详见指令
-
-
## | 引用:
-[Nonebot2] https://github.com/nonebot/nonebot2
-
-[mai-bot] https://github.com/Diving-Fish/mai-bot
-
-[HarukaBot] https://github.com/SK-415/HarukaBot
-
+[Nonebot2](https://github.com/nonebot/nonebot2)
## 命令
-[Pic_menu]
- 菜单
- 菜单 4 2
-
+### 1.[Pic_menu](https://github.com/hamo-reid/nonebot_plugin_PicMenu#%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E6%8F%92%E4%BB%B6) <-点我查看
-[AnimalVoice_Convert]
+### 2.[AnimalVoice_Convert](https://github.com/ANGJustinl/nonebot_plugin_animalVoice)
+
+| 指令 | 需要@ | 范围 | 说明 |
+|:-----:|:----:|:----:|:----:|
`兽音加密`/`convert` | 否 | 群聊/私聊 | 发送需要加密的文字 |
`兽音解密`/`deconvert` | 否 | 群聊/私聊 | 发送需要解密的文字 |
`切噜一下`/`cherulize` | 否 | 群聊/私聊 | 发送需要解密的文字 |
`切噜~`/`decherulize` | 否 | 群聊/私聊 | 发送需要解密的文字 |
-[wallpaper]
+### 3.[wallpaper]
发送`壁纸`获取一张壁纸
发送 `运气检测`
@@ -211,16 +161,10 @@ nonebot_plugin_fortune:https://github.com/MinatoAquaCrews/nonebot_plugin_fortune
api来自 http://api.iw233.cn/API/index.php
`food` 获取食物
-
-`sc + 搜索目标`搜图
-[nonebot-plugin-status]
-✨ NoneBot 服务器状态(CPU, Memory, Disk Usage)查看插件✨:
-向机器人发送戳一戳表情
-`双击机器人头像戳一戳`
+### 4.[nonebot_plugin_setu4](https://github.com/Special-Week/nonebot_plugin_setu4#%E8%8E%B7%E5%8F%96setu) <-点我 查看详解
-[nonebot_plugin_setu4]
内置数据库的setu插件:
命令头: `setu|色图|涩图|想色色|来份色色|来份色图|想涩涩|多来点|来点色图|来张setu|来张色图|来点色色|色色|涩涩` (任意一个)
@@ -239,18 +183,7 @@ api来自 http://api.iw233.cn/API/index.php
> setu 白丝
> setu
-[nonebot-plugin-drawer] 目前因为文心接口原因停止使用
-基于文心大模型的AI机器人画画插件:
-
-触发菜单命令:`画画帮助 当前支持 古风 油画 水彩画 卡通画 二次元 浮世绘 蒸汽波艺术 low poly 像素风格 概念艺术 未来主义 赛博朋克 写实风格 洛丽塔风格 巴洛克风格 超现实主义` 主要擅长风景写意画,请尽量给定比较明确的意象
-
-如:```油画 江上落日与晚霞```
-
->「公式」= 图片主体,细节词,修饰词
-
-api申请https://wenxin.baidu.com/younger/apiDetail?id=20008
-
-[nonebot_plugin_weather_lite]
+### 5.[nonebot_plugin_weather_lite]()
使用wttr.in的天气查询:
命令:
@@ -287,7 +220,7 @@ api申请https://wenxin.baidu.com/younger/apiDetail?id=20008
更多用法请参考wttr.in的文档!
地址:https://github.com/chubin/wttr.in
-[nonebot_plugin_fortune]
+### 6.[nonebot_plugin_fortune](https://github.com/MinatoAquaCrews/nonebot_plugin_fortune#%E5%91%BD%E4%BB%A4)
占卜一下你的今日运势!🎉
@@ -308,40 +241,7 @@ api申请https://wenxin.baidu.com/younger/apiDetail?id=20008
`` 查看(抽签)主题 `` :显示当前已启用主题;
-[HarukaBot b站推送]
-
-(请将UID替换为需要操作的B站UID)
-
-```
-关闭全体 UID
-
-开启全体 UID
-
-开启动态 UID
-
-关闭动态 UID
-
-关闭直播 UID
-
-开启直播 UID
-
-关闭权限
-
-开启权限
-
-关注 UID
-
-取关 UID
-
-关注列表
-
-未改配置群聊中请@机器人使用
-```
-
-[savor]
-```分析 + 图片 分析图片tag```
-
-[pixiv_bot]
+### 7.[pixiv_bot](https://github.com/bot-ssttkkl/nonebot-plugin-pixivbot#%E8%A7%A6%E5%8F%91%E8%AF%AD%E5%8F%A5)
`看看<类型>榜<范围>`:查看pixiv榜单 <类型>可省略
`来<数量>张图`:从推荐插画随机抽选一张插画(<数量>可省略,下同)
@@ -364,30 +264,7 @@ api申请https://wenxin.baidu.com/younger/apiDetail?id=20008
`/pixivbot`、`/pixivbot help`:查看帮助
-[face2cartoonpic]
-`人像变换 + 图片` 可以实现qq的变脸功能
-
-[maimaidx]
-`今日舞萌` 查看今天的舞萌运势
-
-`XXXmaimaiXXX什么` 随机一首歌
-
-`随个[dx/标准][绿黄红紫白]<难度>` 随机一首指定条件的乐曲
-
-`查歌<乐曲标题的一部分>` 查询符合条件的乐曲
-
-`[绿黄红紫白]id<歌曲编号>` 查询乐曲信息或谱面信息
-
-`<歌曲别名>是什么歌` 查询乐曲别名对应的乐曲
-
-`定数查歌 <定数>` 查询定数对应的乐曲
-
-`定数查歌 <定数下限> <定数上限>`
-
-`分数线 <难度+歌曲id> <分数线>` 详情请输入“分数线 帮助”查看
-
----
-
+更详细请见 https://github.com/bot-ssttkkl/nonebot-plugin-pixivbot#%E8%A7%A6%E5%8F%91%E8%AF%AD%E5%8F%A5
## | 👥反馈与交流
@@ -397,16 +274,16 @@ QQ:77139032
群聊:696748432
-
+### 点我加入群聊
-mail:angjustin@163.com
-
-bilibili:https://space.bilibili.com/213993950?spm_id_from=333.1007.0.0
+bilibili:https://space.bilibili.com/213993950
tg:https://t.me/angangbot
---
## | 更新记录
+v2.5.4 2024.02.14 新版文档与全平台适配
+
v2.0.0 2023.09.01 完全重置 适配最新nb
v1.3.2 2023.01.13 细化了github readme
@@ -433,6 +310,8 @@ v1.0.0 2022.10.19 bot初步成型
---
## | 目标:
+- [x] 重写机器人
+- [x] 重写文档
- [ ] Steam_asf的bot进行qq控制
# | EXTRA:
diff --git a/README_old.md b/README_old.md
new file mode 100644
index 0000000..8d76c19
--- /dev/null
+++ b/README_old.md
@@ -0,0 +1,442 @@
+
+
+
+
+
+
+
+
+# ANGANGBOT
+
+✨ 基于NoneBot2的交互bot ✨
+
+
+
+
+
+
+
+
+
+
+
+
+![Alt](https://repobeats.axiom.co/api/embed/6a22c5e973a99b3a396f90ccde21ecfc25c0c2b8.svg "Repobeats analytics image")
+
+
+
+
+ 一切开发旨在学习,请勿用于非法用途
+
+# 新版文档请见 https://github.com/ANGJustinl/ANGANGBOT/README.md (v2+)
+
+
+## | 🚀部署 (可参照 https://angjustinl.github.io/2023/01/06/ANGANGBOT1/ )
+
+---
+
+ | 自建可能会遇到各种花里胡哨的麻烦,如果没有一些基础的话,前面可是困难重重啊少年
+
+ | 本文内容请您自行判断是否可信可靠可用,若您根据本文内容建立和使用AABT时出了任何问题和不良结果,鄙人概不负责。
+
+---
+
+至少需要Python3.9及以上版本(推荐3.10),可通过python -V或python3 -V查看版本号
+
+此 README 提供了最低程度的基于 nonebot 进行安装的教程与支持。
+
+建议您至少拥有一定的编程基础之后再尝试使用本工具。
+
+1. 安装 Python
+
+2. 前往 https://github.com/ANGJustinl/ANGANGBOT/releases 下载lite文件并解压至本地
+
+3. 下载需要的资源文件
+
+ >部分插件需额外下载src文件夹进行替换
+ >
+ >资源文件仅供学习交流使用,请自觉在下载 24 小时内删除资源文件。
+ >
+ >在运行代码之前,您需要从此链接 https://cowtransfer.com/s/c7fa24d11b3949 [传输口令 rt318w]
+ >
+ >下载资源文件并解压到src文件夹中
+
+4. 安装依赖
+
+推荐使用powershell + nb-cil脚手架
+
+Ⅰ. ```pip install nb-cli```
+
+Ⅱ.在项目的根目录(即 bot.py 文件所在的位置)按下 Shift + 右键,点击【在此处打开 PowerShell 窗口】
+
+Ⅲ. ```pip install -r requirements.txt```
+
+3.1 修改[.env.prod]配置文件
+```HOST=127.0.0.1 # Nonebot监听的IP-----1
+
+PORT=10219 # Nonebot监听的端口-----2
+
+LOG_LEVEL=INFO # 日志等级-----3
+
+SUPERUSERS=["12345678"] # 超级用户,修改12345678为你bot管理者的qq号-----4
+
+NICKNAME=["aabt"] # 机器人的昵称-----5
+
+COMMAND_START=[""] # 命令前缀,根据需要自行修改-----6
+
+COMMAND_SEP=[" "] # 命令分隔符-----7
+```
+3.2 修改[.env]配置文件
+
+pixiv功能
+5 ```pixiv_refresh_token = ''``` 写入你p站的refresh_token,具体获取方法自行百度
+
+apex功能
+27 ``` apex_api_key = "" ``` https://portal.apexlegendsapi.com/ 获取token
+
+腾讯云人像变化
+30 `Secret_Id = ""`
+31 ```Secret_Key = ""```
+
+|可选填写部分
+|详见[.env]配置文件内容
+
+4. 启动bot
+
+>部分插件需额外下载src文件夹进行替换
+>
+>资源文件仅供学习交流使用,请自觉在下载 24 小时内删除资源文件。
+>
+>在运行代码之前,您需要从此链接 https://cowtransfer.com/s/c7fa24d11b3949 [传输口令 rt318w]
+>
+>下载资源文件并解压到src文件夹中
+
+推荐使用powershell + nb-cil脚手架
+
+Ⅰ.您可以直接在项目的根目录(即 bot.py 文件所在的位置)按下 Shift + 右键,点击【在此处打开 PowerShell 窗口】
+Ⅱ.
+
+nb run
+
+
+运行项目。如果输出如下所示的内容,代表运行成功:(由于第一次安装不加载配置文件,或许会略有不同,不报错就是没问题的)
+
+> 10-20 16:40:30 [SUCCESS] nonebot | NoneBot is initializing...
+>
+> 10-20 16:40:30 [INFO] nonebot | Current Env: prod
+>
+> 10-20 16:40:31 [SUCCESS] nonebot | Succeeded to import "nonebot_plugin_weather_lite"
+>
+> ......(这里是被加载的插件)
+>
+> 10-20 16:40:32 [SUCCESS] nonebot | Running NoneBot...
+>
+> 10-20 16:40:32 [INFO] uvicorn | Started server process [16676]
+>
+> 10-20 16:40:32 [INFO] uvicorn | Waiting for application startup.
+>
+> 10-20 16:40:32 [INFO] uvicorn | Application startup complete.
+>
+> 10-20 16:40:32 [INFO] uvicorn | Uvicorn running on http://127.0.0.1:10219 (Press CTRL+C to quit)
+
+
+5. 连接 CQ-HTTP
+
+前往 https://github.com/Mrs4s/go-cqhttp > Releases,下载适合自己操作系统的可执行文件。 go-cqhttp 在初次启动时会询问代理方式,选择反向 websocket 代理即可。之后用任何文本编辑器打开config.yml文件,设置反向 ws 地址、上报方式:
+
+```message:
+ post-format: array
+
+servers:
+ - ws-reverse:
+ universal: ws://127.0.0.1:10219/onebot/v11/ws
+```
+
+然后设置您的 QQ 号和密码。您也可以不设置密码,选择扫码登陆的方式。
+
+登陆成功后,后台应该会发送一条类似的信息:
+
+> 10-20 16:40:32 [INFO] nonebot | WebSocket Connection from CQHTTP Bot 114514 Accepted!
+
+至此,您可以和对应的 QQ 号聊天并使用 angangbot 的基础功能了。
+
+
+## | 插件:
+
+对应插件的功能可以自己查询对应插件有关安装方法,此处先不予整合
+
+
+
+## | 插件:
+nonebot-plugin-status:https://github.com/cscs181/QQ-GitHub-Bot/tree/master/src/plugins/nonebot_plugin_status
+
+nonebot_plugin_setu4:https://github.com/Special-Week/nonebot_plugin_setu4
+
+nonebot_plugin_weather_lite:https://github.com/zjkwdy/nonebot_plugin_weather_lite
+
+Nonebot Plugin Hammer Nbnhhsh:https://github.com/ArgonarioD/nonebot-plugin-hammer-nbnhhsh
+
+nonebot_plugin_fortune:https://github.com/MinatoAquaCrews/nonebot_plugin_fortune
+
+...... 目前文档任有不全,具体插件详见指令
+
+
+## | 引用:
+[Nonebot2] https://github.com/nonebot/nonebot2
+
+[mai-bot] https://github.com/Diving-Fish/mai-bot
+
+[HarukaBot] https://github.com/SK-415/HarukaBot
+
+
+## 命令
+
+[Pic_menu]
+ 菜单
+ 菜单 4 2
+
+
+[AnimalVoice_Convert]
+`兽音加密`/`convert` | 否 | 群聊/私聊 | 发送需要加密的文字 |
+`兽音解密`/`deconvert` | 否 | 群聊/私聊 | 发送需要解密的文字 |
+`切噜一下`/`cherulize` | 否 | 群聊/私聊 | 发送需要解密的文字 |
+`切噜~`/`decherulize` | 否 | 群聊/私聊 | 发送需要解密的文字 |
+
+[wallpaper]
+发送`壁纸`获取一张壁纸
+
+发送 `运气检测`
+
+打开随机出一张壁纸
+
+非酋还会刷出来风景图
+
+api来自 http://api.iw233.cn/API/index.php
+
+`food` 获取食物
+
+`sc + 搜索目标`搜图
+
+[nonebot-plugin-status]
+✨ NoneBot 服务器状态(CPU, Memory, Disk Usage)查看插件✨:
+向机器人发送戳一戳表情
+`双击机器人头像戳一戳`
+
+
+[nonebot_plugin_setu4]
+内置数据库的setu插件:
+
+命令头: `setu|色图|涩图|想色色|来份色色|来份色图|想涩涩|多来点|来点色图|来张setu|来张色图|来点色色|色色|涩涩` (任意一个)
+
+张数: `1 2 3 4 ... 张|个|份` (可不填, 默认1)
+
+`r18`: 不填则不会出现r18图片, 填了会根据r18模式管理中的数据判断是否可返回r18图片
+
+关键词: 任意 (可不填)
+
+参考 (空格可去掉):
+
+> setu 10张 r18 白丝
+> setu 10张 白丝
+> setu r18 白丝
+> setu 白丝
+> setu
+
+[nonebot-plugin-drawer] 目前因为文心接口原因停止使用
+基于文心大模型的AI机器人画画插件:
+
+触发菜单命令:`画画帮助 当前支持 古风 油画 水彩画 卡通画 二次元 浮世绘 蒸汽波艺术 low poly 像素风格 概念艺术 未来主义 赛博朋克 写实风格 洛丽塔风格 巴洛克风格 超现实主义` 主要擅长风景写意画,请尽量给定比较明确的意象
+
+如:```油画 江上落日与晚霞```
+
+>「公式」= 图片主体,细节词,修饰词
+
+api申请https://wenxin.baidu.com/younger/apiDetail?id=20008
+
+[nonebot_plugin_weather_lite]
+使用wttr.in的天气查询:
+命令:
+
+注:
+
+ 1.以下天气命令均可以使用wttr、weather、tianqi等效替代,
+
+ 2.城市名可以使用各种语言,例如Beijing、Peking、北京是等效的。
+
+ 3.支持查询全球各种地区。例如莫斯科什么的都可以。
+
+``"天气 城市名"`` (可选,如不给出机器人会提示获取)
+
+`"天气 城市名_format=v2"`
+
+``"天气 城市名_format=v3"``
+
+指定语言:
+
+```
+天气 城市名_lang=语言
+```
+
+语言可选于:
+
+>am ar af be bn ca da de el et fr fa hi hu ia id it lt mg nb nl oc pl pt-br ro ru ta tr th uk vi zh-cn zh-tw
+
+甚至支持看月相:
+
+```
+"天气 Moon"
+```
+
+更多用法请参考wttr.in的文档!
+地址:https://github.com/chubin/wttr.in
+
+[nonebot_plugin_fortune]
+
+占卜一下你的今日运势!🎉
+
+一般抽签:``今日运势、抽签、运势``;
+
+指定主题抽签:`[xx抽签]`,例如:pcr抽签、holo抽签、碧蓝抽签;
+
+[群管或群主或超管] 配置抽签主题:```设置[原神/pcr/东方/vtb/xxx]签```:设置群抽签主题;
+
+``重置(抽签)主题``:设置群抽签主题为随机;
+
+``抽签设置``:查看当前群抽签主题的配置;
+
+[超管] `` 刷新抽签 `` :全局即刻刷新抽签,防止过0点未刷新;
+
+`` 今日运势帮助 `` :显示插件帮助文案;
+
+`` 查看(抽签)主题 `` :显示当前已启用主题;
+
+
+[HarukaBot b站推送]
+
+(请将UID替换为需要操作的B站UID)
+
+```
+关闭全体 UID
+
+开启全体 UID
+
+开启动态 UID
+
+关闭动态 UID
+
+关闭直播 UID
+
+开启直播 UID
+
+关闭权限
+
+开启权限
+
+关注 UID
+
+取关 UID
+
+关注列表
+
+未改配置群聊中请@机器人使用
+```
+
+[savor]
+```分析 + 图片 分析图片tag```
+
+[pixiv_bot]
+`看看<类型>榜<范围>`:查看pixiv榜单 <类型>可省略
+
+`来<数量>张图`:从推荐插画随机抽选一张插画(<数量>可省略,下同)
+
+`来<数量>张<关键字>图`:搜索关键字,从搜索结果随机抽选一张插画
+
+>示例:来张初音ミク图、来五张初音ミク图
+
+`来<数量>张<用户>老师的图`:搜索用户,从插画列表中随机抽选一张插画
+
+`看看图<插画ID>`:查看ID对应的插画
+
+>示例:看看图114514
+
+`来<数量>张私家车`:从书签中随机抽选一张插画(发送者需绑定Pixiv账号,或者在配置中指定默认Pixiv账号)
+
+`/pixivbot bind `:绑定Pixiv账号(用于随机书签功能)
+
+`/pixivbot unbind`:解绑Pixiv账号
+
+`/pixivbot`、`/pixivbot help`:查看帮助
+
+[face2cartoonpic]
+`人像变换 + 图片` 可以实现qq的变脸功能
+
+[maimaidx]
+`今日舞萌` 查看今天的舞萌运势
+
+`XXXmaimaiXXX什么` 随机一首歌
+
+`随个[dx/标准][绿黄红紫白]<难度>` 随机一首指定条件的乐曲
+
+`查歌<乐曲标题的一部分>` 查询符合条件的乐曲
+
+`[绿黄红紫白]id<歌曲编号>` 查询乐曲信息或谱面信息
+
+`<歌曲别名>是什么歌` 查询乐曲别名对应的乐曲
+
+`定数查歌 <定数>` 查询定数对应的乐曲
+
+`定数查歌 <定数下限> <定数上限>`
+
+`分数线 <难度+歌曲id> <分数线>` 详情请输入“分数线 帮助”查看
+
+---
+
+
+## | 👥反馈与交流
+
+### Issue for sure
+
+QQ:77139032
+
+群聊:696748432
+
+
+
+mail:angjustin@163.com
+
+bilibili:https://space.bilibili.com/213993950?spm_id_from=333.1007.0.0
+
+tg:https://t.me/angangbot
+
+---
+## | 更新记录
+v2.0.0 2023.09.01 完全重置 适配最新nb
+
+v1.3.2 2023.01.13 细化了github readme
+
+v1.3.1 2023.01.05 编辑了文档
+
+v1.3 2022 12.30 推倒重来了大部分内容,1.3后的详见新的分支
+
+v1.2 2022.12.20
+
+v1.1.6 2022.10.23 重写了help获取帮助命令cv2内容
+
+v1.1.5 2022.10.22 配置了APEX查分插件,改了部分插件内容
+
+v1.1.4 2022.10.22 添加舞萌DX插件相关内容
+
+v1.1.2 2022.10.21 添加了部分插件,优化了requirements.txt内容
+
+v1.1.0 2022.10.20 上传至git
+
+v1.0.1 2022.10.19 完成了bot的配置流程
+
+v1.0.0 2022.10.19 bot初步成型
+
+---
+## | 目标:
+- [ ] Steam_asf的bot进行qq控制
+
+# | EXTRA:
+https://afdian.net/a/angjustinl
diff --git a/bot.py b/bot.py
index 823c7f2..cf49512 100644
--- a/bot.py
+++ b/bot.py
@@ -4,7 +4,6 @@
from nonebot.adapters.onebot.v11 import Adapter as ONEBOT_V11Adapter
-
nonebot.init()
app = nonebot.get_asgi()
@@ -15,17 +14,12 @@
require("nonebot_plugin_guild_patch")
nonebot.load_plugin('nonebot_plugin_pixivbot')
-nonebot.load_plugin('nonebot_plugin_pjsk')
nonebot.load_plugin('nonebot_plugin_setu4')
-nonebot.load_plugin('nonebot_plugin_HttpCat')
-nonebot.load_plugin('nonebot_plugin_broadcast')
-#nonebot.load_plugin('nonebot_plugin_wordcloud')
nonebot.load_plugin('nonebot_plugin_tarot')
nonebot.load_plugin('nonebot_plugin_fortune')
-nonebot.load_plugin('nonebot_plugin_eventdone')
+
nonebot.load_plugin('nonebot_plugin_PicMenu')
nonebot.load_plugin('nonebot_plugin_weather_lite')
-nonebot.load_plugin('nonebot-plugin-random')
#nonebot.load_plugin('nonebot_plugin_bili_push')
diff --git a/data/setu4/setu_perm_cfg.json b/data/setu4/setu_perm_cfg.json
index 342ad64..7ad46e9 100644
--- a/data/setu4/setu_perm_cfg.json
+++ b/data/setu4/setu_perm_cfg.json
@@ -1 +1 @@
-{"proxy": "i.pixiv.re", "last": {"group_261796171": 1693025711.3414242, "group_789731815": 1693050122.293585, "group_696748432": 1695548715.2781172, "group_1003802944": 1695549545.1488266, "group_554646751": 1695552176.541681}, "group_1003802944": {}, "group_484428662": {}, "group_696748432": {}, "group_789731815": {"cd": 10}, "group_771686548": {}, "group_554646751": {}, "group_473195097": {}}
\ No newline at end of file
+{"proxy": "i.pixiv.re"}
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index fab3b4c..0000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-version: "3"
-
-x-config-host: &config-host ${HOST:-0.0.0.0}
-x-config-port: &config-port ${PORT:-8080}
-
-services:
- nonebot:
- build: .
- ports:
- - *config-port
- env_file:
- - .env.prod
- environment:
- ENVIRONMENT: prod
- HOST: *config-host
- PORT: *config-port
- restart: always
\ No newline at end of file
diff --git a/docker/_main.py b/docker/_main.py
deleted file mode 100644
index 3cbb5c3..0000000
--- a/docker/_main.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import bot
-import nonebot
-
-app = nonebot.get_asgi()
diff --git a/docker/gunicorn_conf.py b/docker/gunicorn_conf.py
deleted file mode 100644
index 073d631..0000000
--- a/docker/gunicorn_conf.py
+++ /dev/null
@@ -1,82 +0,0 @@
-import os
-import json
-import multiprocessing
-
-host = os.getenv("HOST", "0.0.0.0")
-port = os.getenv("PORT", "8080")
-bind_env = os.getenv("BIND", None)
-use_bind = bind_env or f"{host}:{port}"
-
-use_loglevel = os.getenv("LOG_LEVEL", "info")
-accesslog_var = os.getenv("ACCESS_LOG", "-")
-use_accesslog = accesslog_var or None
-errorlog_var = os.getenv("ERROR_LOG", "-")
-use_errorlog = errorlog_var or None
-
-cores = multiprocessing.cpu_count()
-workers_per_core_str = os.getenv("WORKERS_PER_CORE", "1")
-workers_per_core = float(workers_per_core_str)
-default_web_concurrency = workers_per_core * cores
-max_workers_str = os.getenv("MAX_WORKERS")
-use_max_workers = int(max_workers_str) if max_workers_str else None
-if web_concurrency_str := os.getenv("WEB_CONCURRENCY", None):
- web_concurrency = int(web_concurrency_str)
- assert web_concurrency > 0
-else:
- web_concurrency = max(int(default_web_concurrency), 2)
- if use_max_workers:
- web_concurrency = min(web_concurrency, use_max_workers)
-
-graceful_timeout_str = os.getenv("GRACEFUL_TIMEOUT", "120")
-timeout_str = os.getenv("TIMEOUT", "120")
-keepalive_str = os.getenv("KEEP_ALIVE", "5")
-
-# Gunicorn config variables
-loglevel = use_loglevel
-workers = web_concurrency
-bind = use_bind
-errorlog = use_errorlog
-worker_tmp_dir = "/dev/shm"
-accesslog = use_accesslog
-graceful_timeout = int(graceful_timeout_str)
-timeout = int(timeout_str)
-keepalive = int(keepalive_str)
-keyfile = os.getenv("KEYFILE", None)
-certfile = os.getenv("CERTFILE", None)
-
-logconfig_dict = {
- "root": {"level": "INFO", "handlers": ["default"]},
- "handlers": {"default": {"class": "nonebot.log.LoguruHandler"}},
- "loggers": {
- "gunicorn.error": {
- "level": "INFO",
- "handlers": ["default"],
- "propagate": True,
- "qualname": "gunicorn.error",
- },
- "gunicorn.access": {
- "level": "INFO",
- "handlers": ["default"],
- "propagate": True,
- "qualname": "gunicorn.access",
- },
- },
-}
-
-# For debugging and testing
-log_data = {
- "loglevel": loglevel,
- "workers": workers,
- "bind": bind,
- "graceful_timeout": graceful_timeout,
- "timeout": timeout,
- "keepalive": keepalive,
- "errorlog": errorlog,
- "accesslog": accesslog,
- # Additional, non-gunicorn variables
- "workers_per_core": workers_per_core,
- "use_max_workers": use_max_workers,
- "host": host,
- "port": port,
-}
-print(json.dumps(log_data))
diff --git a/docker/start.sh b/docker/start.sh
deleted file mode 100644
index 2f1891e..0000000
--- a/docker/start.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#! /usr/bin/env sh
-set -e
-
-if [ -f /app/app/main.py ]; then
- DEFAULT_MODULE_NAME=app.main
-elif [ -f /app/main.py ]; then
- DEFAULT_MODULE_NAME=main
-fi
-MODULE_NAME=${MODULE_NAME:-$DEFAULT_MODULE_NAME}
-VARIABLE_NAME=${VARIABLE_NAME:-app}
-export APP_MODULE=${APP_MODULE:-"$MODULE_NAME:$VARIABLE_NAME"}
-
-if [ -f /app/gunicorn_conf.py ]; then
- DEFAULT_GUNICORN_CONF=/app/gunicorn_conf.py
-elif [ -f /app/app/gunicorn_conf.py ]; then
- DEFAULT_GUNICORN_CONF=/app/app/gunicorn_conf.py
-else
- DEFAULT_GUNICORN_CONF=/gunicorn_conf.py
-fi
-export GUNICORN_CONF=${GUNICORN_CONF:-$DEFAULT_GUNICORN_CONF}
-export WORKER_CLASS=${WORKER_CLASS:-"uvicorn.workers.UvicornWorker"}
-
-# If there's a prestart.sh script in the /app directory or other path specified, run it before starting
-PRE_START_PATH=${PRE_START_PATH:-/app/prestart.sh}
-echo "Checking for script in $PRE_START_PATH"
-if [ -f $PRE_START_PATH ]; then
- echo "Running script $PRE_START_PATH"
- . "$PRE_START_PATH"
-else
- echo "There is no script $PRE_START_PATH"
-fi
-
-# Start Gunicorn
-exec gunicorn -k "$WORKER_CLASS" -c "$GUNICORN_CONF" "$APP_MODULE"
diff --git a/enviroment.yml b/enviroment.yml
deleted file mode 100644
index 1b0920d..0000000
--- a/enviroment.yml
+++ /dev/null
@@ -1,244 +0,0 @@
-name: nb
-channels:
- - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/linux-64/
- - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
- - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
- - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
- - defaults
-dependencies:
- - _libgcc_mutex=0.1=main
- - _openmp_mutex=5.1=1_gnu
- - bzip2=1.0.8=h7b6447c_0
- - ca-certificates=2023.05.30=h06a4308_0
- - ld_impl_linux-64=2.38=h1181459_1
- - libffi=3.4.4=h6a678d5_0
- - libgcc-ng=11.2.0=h1234567_1
- - libgomp=11.2.0=h1234567_1
- - libstdcxx-ng=11.2.0=h1234567_1
- - libuuid=1.41.5=h5eee18b_0
- - ncurses=6.4=h6a678d5_0
- - openssl=3.0.9=h7f8727e_0
- - pip=23.1.2=py310h06a4308_0
- - python=3.10.11=h955ad1f_3
- - readline=8.2=h5eee18b_0
- - setuptools=67.8.0=py310h06a4308_0
- - sqlite=3.41.2=h5eee18b_0
- - tk=8.6.12=h1ccaba5_0
- - wheel=0.38.4=py310h06a4308_0
- - xz=5.4.2=h5eee18b_0
- - zlib=1.2.13=h5eee18b_0
- - pip:
- - aiocache==0.11.1
- - aiofiles==23.2.1
- - aiohttp==3.8.5
- - aiohttp-socks==0.8.0
- - aiosignal==1.3.1
- - aiosqlite==0.19.0
- - alembic==1.12.0
- - anyio==3.7.1
- - apscheduler==3.10.4
- - arclet-alconna==1.7.22
- - arclet-alconna-tools==0.6.7
- - arrow==1.2.3
- - async-timeout==4.0.3
- - asyncache==0.3.1
- - asyncmy==0.2.8
- - asyncodbc==0.1.1
- - asyncpg==0.27.0
- - attrs==23.1.0
- - bbcode==1.1.0
- - beautifulsoup4==4.12.2
- - bilireq==0.2.6
- - binaryornot==0.4.4
- - build==0.10.0
- - cachecontrol==0.13.1
- - cachetools==5.3.1
- - cashews==6.2.0
- - certifi==2023.7.22
- - cffi==1.16.0
- - cfgv==3.4.0
- - chardet==5.1.0
- - charset-normalizer==3.2.0
- - cleo==2.0.1
- - click==8.1.7
- - colorama==0.4.6
- - contourpy==1.1.0
- - cookiecutter==2.1.1
- - crashtest==0.4.1
- - cryptography==41.0.4
- - cssselect==1.2.0
- - cycler==0.11.0
- - deprecated==1.2.14
- - distlib==0.3.7
- - dulwich==0.21.6
- - emoji==2.6.0
- - exceptiongroup==1.1.3
- - expiringdict==1.2.2
- - fastapi==0.103.1
- - filelock==3.12.2
- - fonttools==4.40.0
- - frozendict==2.3.8
- - frozenlist==1.4.0
- - fuzzywuzzy==0.18.0
- - greenlet==2.0.2
- - grpcio==1.56.0
- - h11==0.14.0
- - h2==4.1.0
- - haruka-bot==1.6.0post4
- - hpack==4.0.0
- - httpcore==0.17.3
- - httptools==0.6.0
- - httpx==0.24.1
- - hyperframe==6.0.1
- - identify==2.5.29
- - idna==3.4
- - imagetext-py==2.1.3
- - importlib-metadata==6.8.0
- - install==1.3.5
- - installer==0.7.0
- - iso8601==1.1.0
- - jaraco-classes==3.3.0
- - jeepney==0.8.0
- - jieba==0.42.1
- - jinja2==3.1.2
- - jinja2-time==0.2.0
- - jsonschema==4.17.3
- - keyring==24.2.0
- - kiwisolver==1.4.4
- - lazy==1.6
- - levenshtein==0.21.1
- - loguru==0.7.2
- - lxml==4.9.3
- - mako==1.2.4
- - markupsafe==2.1.3
- - matplotlib==3.7.1
- - more-itertools==10.1.0
- - msgpack==1.0.5
- - multidict==6.0.4
- - nb-cli==1.1.2
- - nb-cli-plugin-docker==0.3.0
- - nepattern==0.5.14
- - nodeenv==1.8.0
- - nonebot-adapter-onebot==2.3.1
- - nonebot-plugin-access-control==0.6.4
- - nonebot-plugin-alconna==0.24.0
- - nonebot-plugin-apscheduler==0.3.0
- - nonebot-plugin-batitle==0.1.4
- - nonebot-plugin-bili-push==0.1.35
- - nonebot-plugin-bilibilibot==2.3.3
- - nonebot-plugin-broadcast==0.1.0
- - nonebot-plugin-cesaa==0.1.0
- - nonebot-plugin-chatrecorder==0.4.1
- - nonebot-plugin-datastore==1.1.2
- - nonebot-plugin-eventdone==1.1.1
- - nonebot-plugin-flexperm==0.7.0
- - nonebot-plugin-fortune==0.4.11.post1
- - nonebot-plugin-gocqhttp-cross-machine-upload-file==0.1.5
- - nonebot-plugin-group-link-guild==0.0.6
- - nonebot-plugin-guild-patch==0.2.3
- - nonebot-plugin-httpcat==0.0.2
- - nonebot-plugin-imageutils==0.1.17
- - nonebot-plugin-impact==0.9.114514
- - nonebot-plugin-localstore==0.5.1
- - nonebot-plugin-manager==0.5.16
- - nonebot-plugin-picmenu==0.2
- - nonebot-plugin-picsearcher==0.1.10
- - nonebot-plugin-picstatus==0.5.1
- - nonebot-plugin-pixivbot==2.0.4
- - nonebot-plugin-pjsk==0.2.8
- - nonebot-plugin-random==0.0.9
- - nonebot-plugin-savor==0.2.1
- - nonebot-plugin-send-anything-anywhere==0.3.0
- - nonebot-plugin-session==0.1.0
- - nonebot-plugin-setu4==0.1.114514
- - nonebot-plugin-tarot==0.4.0.post4
- - nonebot-plugin-tortoise-orm==0.1.1
- - nonebot-plugin-update==0.1.3
- - nonebot-plugin-uvdiviner==2.2.0.6
- - nonebot-plugin-weather-lite==0.0.1
- - nonebot-plugin-wordcloud==0.5.2
- - nonebot2==2.1.0
- - noneprompt==0.1.9
- - numpy==1.26.0
- - opencv-python-headless==4.8.0.76
- - packaging==23.1
- - pexpect==4.8.0
- - picimagesearch==3.9.5
- - pil-utils==0.1.7
- - pillow==9.5.0
- - pixivpy-async==1.2.14
- - pkginfo==1.9.6
- - platformdirs==2.6.2
- - playwright==1.35.0
- - poetry==1.6.1
- - poetry-core==1.7.0
- - poetry-plugin-export==1.5.0
- - pre-commit==3.4.0
- - prompt-toolkit==3.0.38
- - protobuf==4.23.3
- - psutil==5.9.5
- - ptyprocess==0.7.0
- - pyasn1==0.5.0
- - pycparser==2.21
- - pydantic==1.10.12
- - pyee==9.0.4
- - pyfiglet==0.8.post1
- - pygtrie==2.5.0
- - pyodbc==4.0.39
- - pyparsing==3.1.0
- - pypika-tortoise==0.1.6
- - pyproject-hooks==1.0.0
- - pyproject-toml==0.0.11
- - pyquery==2.0.0
- - pyrsistent==0.19.3
- - python-dateutil==2.8.2
- - python-dotenv==1.0.0
- - python-levenshtein==0.21.1
- - python-slugify==8.0.1
- - python-socks==2.3.0
- - pytimeparser==0.2.0
- - pytz==2023.3.post1
- - pyyaml==6.0.1
- - rapidfuzz==2.15.1
- - requests==2.31.0
- - requests-toolbelt==1.0.0
- - rfc3986==1.5.0
- - rsa==4.9
- - ruamel-yaml==0.17.32
- - ruamel-yaml-clib==0.2.7
- - secretstorage==3.3.3
- - shellingham==1.5.3
- - shelved-cache==0.3.1
- - shortuuid==1.0.11
- - six==1.16.0
- - sniffio==1.3.0
- - soupsieve==2.4.1
- - sqlalchemy==2.0.21
- - ssttkkl-nonebot-utils==0.1.15
- - starlette==0.27.0
- - strenum==0.4.15
- - tarina==0.4.1
- - tenacity==8.2.3
- - text-unidecode==1.3
- - toml==0.10.2
- - tomli==2.0.1
- - tomlkit==0.11.8
- - tortoise-orm==0.19.3
- - trove-classifiers==2023.9.19
- - typing-extensions==4.8.0
- - tzdata==2023.3
- - tzlocal==5.0.1
- - urllib3==2.0.3
- - uvdiviner==2.1.4
- - uvicorn==0.23.2
- - uvloop==0.17.0
- - virtualenv==20.17.1
- - watchfiles==0.20.0
- - wcwidth==0.2.6
- - websockets==11.0.3
- - wordcloud==1.9.2
- - wrapt==1.15.0
- - yarl==1.9.2
- - yetanotherpicsearch==1.9.4
- - zipp==3.17.0
-prefix: /root/miniconda3/envs/nb
diff --git a/poetry.lock b/poetry.lock
new file mode 100644
index 0000000..676c832
--- /dev/null
+++ b/poetry.lock
@@ -0,0 +1,2167 @@
+# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
+
+[[package]]
+name = "anyio"
+version = "3.7.1"
+description = "High level compatibility layer for multiple asynchronous event loop implementations"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"},
+ {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"},
+]
+
+[package.dependencies]
+exceptiongroup = {version = "*", markers = "python_version < \"3.11\""}
+idna = ">=2.8"
+sniffio = ">=1.1"
+
+[package.extras]
+doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"]
+test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
+trio = ["trio (<0.22)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "apscheduler"
+version = "3.10.4"
+description = "In-process task scheduler with Cron-like capabilities"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "APScheduler-3.10.4-py3-none-any.whl", hash = "sha256:fb91e8a768632a4756a585f79ec834e0e27aad5860bac7eaa523d9ccefd87661"},
+ {file = "APScheduler-3.10.4.tar.gz", hash = "sha256:e6df071b27d9be898e486bc7940a7be50b4af2e9da7c08f0744a96d4bd4cef4a"},
+]
+
+[package.dependencies]
+pytz = "*"
+six = ">=1.4.0"
+tzlocal = ">=2.0,<3.dev0 || >=4.dev0"
+
+[package.extras]
+doc = ["sphinx", "sphinx-rtd-theme"]
+gevent = ["gevent"]
+mongodb = ["pymongo (>=3.0)"]
+redis = ["redis (>=3.0)"]
+rethinkdb = ["rethinkdb (>=2.4.0)"]
+sqlalchemy = ["sqlalchemy (>=1.4)"]
+testing = ["pytest", "pytest-asyncio", "pytest-cov", "pytest-tornado5"]
+tornado = ["tornado (>=4.3)"]
+twisted = ["twisted"]
+zookeeper = ["kazoo"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "arrow"
+version = "1.3.0"
+description = "Better dates & times for Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"},
+ {file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"},
+]
+
+[package.dependencies]
+python-dateutil = ">=2.7.0"
+types-python-dateutil = ">=2.8.10"
+
+[package.extras]
+doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"]
+test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "binaryornot"
+version = "0.4.4"
+description = "Ultra-lightweight pure Python package to check if a file is binary or text."
+optional = false
+python-versions = "*"
+files = [
+ {file = "binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4"},
+ {file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"},
+]
+
+[package.dependencies]
+chardet = ">=3.0.2"
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "cashews"
+version = "6.4.0"
+description = "cache tools with async power"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "cashews-6.4.0-py3-none-any.whl", hash = "sha256:6b7121a0629a17aa72d22bf4007462a9fbcdcd418b8ec1083f2806950c265e58"},
+ {file = "cashews-6.4.0.tar.gz", hash = "sha256:0f5ec89b4e8d2944e9403c5fc24fb2947003d279e338de40f2fd3ebc9145c4e3"},
+]
+
+[package.extras]
+dill = ["dill"]
+diskcache = ["diskcache (>=5.0.0)"]
+lint = ["mypy (>=1.5.0)", "types-redis"]
+redis = ["redis (>=4.3.1,!=5.0.1)"]
+speedup = ["bitarray (<3.0.0)", "hiredis", "xxhash (<4.0.0)"]
+tests = ["hypothesis", "pytest", "pytest-asyncio (==0.23.3)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "certifi"
+version = "2024.2.2"
+description = "Python package for providing Mozilla's CA Bundle."
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"},
+ {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "chardet"
+version = "5.2.0"
+description = "Universal encoding detector for Python 3"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"},
+ {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "charset-normalizer"
+version = "3.3.2"
+description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
+optional = false
+python-versions = ">=3.7.0"
+files = [
+ {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"},
+ {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"},
+ {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"},
+ {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"},
+ {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"},
+ {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"},
+ {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"},
+ {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "click"
+version = "8.1.7"
+description = "Composable command line interface toolkit"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
+ {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "platform_system == \"Windows\""}
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+description = "Cross-platform colored terminal text."
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+files = [
+ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
+ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "cookiecutter"
+version = "2.5.0"
+description = "A command-line utility that creates projects from project templates, e.g. creating a Python package project from a Python package project template."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "cookiecutter-2.5.0-py3-none-any.whl", hash = "sha256:8aa2f12ed11bc05628651e9dc4353a10571dd9908aaaaeec959a2b9ea465a5d2"},
+ {file = "cookiecutter-2.5.0.tar.gz", hash = "sha256:e61e9034748e3f41b8bd2c11f00d030784b48711c4d5c42363c50989a65331ec"},
+]
+
+[package.dependencies]
+arrow = "*"
+binaryornot = ">=0.4.4"
+click = ">=7.0,<9.0.0"
+Jinja2 = ">=2.7,<4.0.0"
+python-slugify = ">=4.0.0"
+pyyaml = ">=5.3.1"
+requests = ">=2.23.0"
+rich = "*"
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "distlib"
+version = "0.3.8"
+description = "Distribution utilities"
+optional = false
+python-versions = "*"
+files = [
+ {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"},
+ {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "exceptiongroup"
+version = "1.2.0"
+description = "Backport of PEP 654 (exception groups)"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"},
+ {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"},
+]
+
+[package.extras]
+test = ["pytest (>=6)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "fastapi"
+version = "0.109.2"
+description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "fastapi-0.109.2-py3-none-any.whl", hash = "sha256:2c9bab24667293b501cad8dd388c05240c850b58ec5876ee3283c47d6e1e3a4d"},
+ {file = "fastapi-0.109.2.tar.gz", hash = "sha256:f3817eac96fe4f65a2ebb4baa000f394e55f5fccdaf7f75250804bc58f354f73"},
+]
+
+[package.dependencies]
+pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0"
+starlette = ">=0.36.3,<0.37.0"
+typing-extensions = ">=4.8.0"
+
+[package.extras]
+all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "filelock"
+version = "3.13.1"
+description = "A platform independent file lock."
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"},
+ {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"},
+]
+
+[package.extras]
+docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"]
+testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"]
+typing = ["typing-extensions (>=4.8)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "fuzzywuzzy"
+version = "0.18.0"
+description = "Fuzzy string matching in python"
+optional = false
+python-versions = "*"
+files = [
+ {file = "fuzzywuzzy-0.18.0-py2.py3-none-any.whl", hash = "sha256:928244b28db720d1e0ee7587acf660ea49d7e4c632569cad4f1cd7e68a5f0993"},
+ {file = "fuzzywuzzy-0.18.0.tar.gz", hash = "sha256:45016e92264780e58972dca1b3d939ac864b78437422beecebb3095f8efd00e8"},
+]
+
+[package.extras]
+speedup = ["python-levenshtein (>=0.12)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "h11"
+version = "0.14.0"
+description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
+ {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "httpcore"
+version = "1.0.2"
+description = "A minimal low-level HTTP client."
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7"},
+ {file = "httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535"},
+]
+
+[package.dependencies]
+certifi = "*"
+h11 = ">=0.13,<0.15"
+
+[package.extras]
+asyncio = ["anyio (>=4.0,<5.0)"]
+http2 = ["h2 (>=3,<5)"]
+socks = ["socksio (==1.*)"]
+trio = ["trio (>=0.22.0,<0.23.0)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "httptools"
+version = "0.6.1"
+description = "A collection of framework independent HTTP protocol utils."
+optional = false
+python-versions = ">=3.8.0"
+files = [
+ {file = "httptools-0.6.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f"},
+ {file = "httptools-0.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563"},
+ {file = "httptools-0.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58"},
+ {file = "httptools-0.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185"},
+ {file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142"},
+ {file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658"},
+ {file = "httptools-0.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b"},
+ {file = "httptools-0.6.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1"},
+ {file = "httptools-0.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0"},
+ {file = "httptools-0.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc"},
+ {file = "httptools-0.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2"},
+ {file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837"},
+ {file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d"},
+ {file = "httptools-0.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3"},
+ {file = "httptools-0.6.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0"},
+ {file = "httptools-0.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2"},
+ {file = "httptools-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90"},
+ {file = "httptools-0.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503"},
+ {file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84"},
+ {file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb"},
+ {file = "httptools-0.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949"},
+ {file = "httptools-0.6.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8e216a038d2d52ea13fdd9b9c9c7459fb80d78302b257828285eca1c773b99b3"},
+ {file = "httptools-0.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3e802e0b2378ade99cd666b5bffb8b2a7cc8f3d28988685dc300469ea8dd86cb"},
+ {file = "httptools-0.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd3e488b447046e386a30f07af05f9b38d3d368d1f7b4d8f7e10af85393db97"},
+ {file = "httptools-0.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3"},
+ {file = "httptools-0.6.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3c3b214ce057c54675b00108ac42bacf2ab8f85c58e3f324a4e963bbc46424f4"},
+ {file = "httptools-0.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ae5b97f690badd2ca27cbf668494ee1b6d34cf1c464271ef7bfa9ca6b83ffaf"},
+ {file = "httptools-0.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:405784577ba6540fa7d6ff49e37daf104e04f4b4ff2d1ac0469eaa6a20fde084"},
+ {file = "httptools-0.6.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:95fb92dd3649f9cb139e9c56604cc2d7c7bf0fc2e7c8d7fbd58f96e35eddd2a3"},
+ {file = "httptools-0.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dcbab042cc3ef272adc11220517278519adf8f53fd3056d0e68f0a6f891ba94e"},
+ {file = "httptools-0.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf2372e98406efb42e93bfe10f2948e467edfd792b015f1b4ecd897903d3e8d"},
+ {file = "httptools-0.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:678fcbae74477a17d103b7cae78b74800d795d702083867ce160fc202104d0da"},
+ {file = "httptools-0.6.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e0b281cf5a125c35f7f6722b65d8542d2e57331be573e9e88bc8b0115c4a7a81"},
+ {file = "httptools-0.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:95658c342529bba4e1d3d2b1a874db16c7cca435e8827422154c9da76ac4e13a"},
+ {file = "httptools-0.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ebaec1bf683e4bf5e9fbb49b8cc36da482033596a415b3e4ebab5a4c0d7ec5e"},
+ {file = "httptools-0.6.1.tar.gz", hash = "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a"},
+]
+
+[package.extras]
+test = ["Cython (>=0.29.24,<0.30.0)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "httpx"
+version = "0.26.0"
+description = "The next generation HTTP client."
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"},
+ {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"},
+]
+
+[package.dependencies]
+anyio = "*"
+certifi = "*"
+httpcore = "==1.*"
+idna = "*"
+sniffio = "*"
+
+[package.extras]
+brotli = ["brotli", "brotlicffi"]
+cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"]
+http2 = ["h2 (>=3,<5)"]
+socks = ["socksio (==1.*)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "idna"
+version = "3.6"
+description = "Internationalized Domain Names in Applications (IDNA)"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"},
+ {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "jinja2"
+version = "3.1.3"
+description = "A very fast and expressive template engine."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"},
+ {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"},
+]
+
+[package.dependencies]
+MarkupSafe = ">=2.0"
+
+[package.extras]
+i18n = ["Babel (>=2.7)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "loguru"
+version = "0.7.2"
+description = "Python logging made (stupidly) simple"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb"},
+ {file = "loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"},
+]
+
+[package.dependencies]
+colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""}
+win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""}
+
+[package.extras]
+dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.4.1)", "mypy (==v1.5.1)", "pre-commit (==3.4.0)", "pytest (==6.1.2)", "pytest (==7.4.0)", "pytest-cov (==2.12.1)", "pytest-cov (==4.1.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.0.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.3.0)", "tox (==3.27.1)", "tox (==4.11.0)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "markdown-it-py"
+version = "3.0.0"
+description = "Python port of markdown-it. Markdown parsing, done right!"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"},
+ {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"},
+]
+
+[package.dependencies]
+mdurl = ">=0.1,<1.0"
+
+[package.extras]
+benchmarking = ["psutil", "pytest", "pytest-benchmark"]
+code-style = ["pre-commit (>=3.0,<4.0)"]
+compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"]
+linkify = ["linkify-it-py (>=1,<3)"]
+plugins = ["mdit-py-plugins"]
+profiling = ["gprof2dot"]
+rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"]
+testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "markupsafe"
+version = "2.1.5"
+description = "Safely add untrusted strings to HTML/XML markup."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"},
+ {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"},
+ {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"},
+ {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"},
+ {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"},
+ {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"},
+ {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"},
+ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "mdurl"
+version = "0.1.2"
+description = "Markdown URL utilities"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
+ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "msgpack"
+version = "1.0.7"
+description = "MessagePack serializer"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862"},
+ {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329"},
+ {file = "msgpack-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b"},
+ {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6"},
+ {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee"},
+ {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d"},
+ {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d"},
+ {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1"},
+ {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681"},
+ {file = "msgpack-1.0.7-cp310-cp310-win32.whl", hash = "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9"},
+ {file = "msgpack-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415"},
+ {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84"},
+ {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93"},
+ {file = "msgpack-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8"},
+ {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46"},
+ {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b"},
+ {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e"},
+ {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002"},
+ {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c"},
+ {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e"},
+ {file = "msgpack-1.0.7-cp311-cp311-win32.whl", hash = "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1"},
+ {file = "msgpack-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82"},
+ {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b"},
+ {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4"},
+ {file = "msgpack-1.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee"},
+ {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5"},
+ {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672"},
+ {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075"},
+ {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba"},
+ {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c"},
+ {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5"},
+ {file = "msgpack-1.0.7-cp312-cp312-win32.whl", hash = "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9"},
+ {file = "msgpack-1.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf"},
+ {file = "msgpack-1.0.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5b6ccc0c85916998d788b295765ea0e9cb9aac7e4a8ed71d12e7d8ac31c23c95"},
+ {file = "msgpack-1.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:235a31ec7db685f5c82233bddf9858748b89b8119bf4538d514536c485c15fe0"},
+ {file = "msgpack-1.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cab3db8bab4b7e635c1c97270d7a4b2a90c070b33cbc00c99ef3f9be03d3e1f7"},
+ {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bfdd914e55e0d2c9e1526de210f6fe8ffe9705f2b1dfcc4aecc92a4cb4b533d"},
+ {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36e17c4592231a7dbd2ed09027823ab295d2791b3b1efb2aee874b10548b7524"},
+ {file = "msgpack-1.0.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38949d30b11ae5f95c3c91917ee7a6b239f5ec276f271f28638dec9156f82cfc"},
+ {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ff1d0899f104f3921d94579a5638847f783c9b04f2d5f229392ca77fba5b82fc"},
+ {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dc43f1ec66eb8440567186ae2f8c447d91e0372d793dfe8c222aec857b81a8cf"},
+ {file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dd632777ff3beaaf629f1ab4396caf7ba0bdd075d948a69460d13d44357aca4c"},
+ {file = "msgpack-1.0.7-cp38-cp38-win32.whl", hash = "sha256:4e71bc4416de195d6e9b4ee93ad3f2f6b2ce11d042b4d7a7ee00bbe0358bd0c2"},
+ {file = "msgpack-1.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:8f5b234f567cf76ee489502ceb7165c2a5cecec081db2b37e35332b537f8157c"},
+ {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f"},
+ {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81"},
+ {file = "msgpack-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc"},
+ {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d"},
+ {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7"},
+ {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61"},
+ {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819"},
+ {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd"},
+ {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f"},
+ {file = "msgpack-1.0.7-cp39-cp39-win32.whl", hash = "sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad"},
+ {file = "msgpack-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3"},
+ {file = "msgpack-1.0.7.tar.gz", hash = "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "multidict"
+version = "6.0.5"
+description = "multidict implementation"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9"},
+ {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604"},
+ {file = "multidict-6.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600"},
+ {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c"},
+ {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5"},
+ {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f"},
+ {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae"},
+ {file = "multidict-6.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182"},
+ {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf"},
+ {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442"},
+ {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a"},
+ {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef"},
+ {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc"},
+ {file = "multidict-6.0.5-cp310-cp310-win32.whl", hash = "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319"},
+ {file = "multidict-6.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8"},
+ {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba"},
+ {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e"},
+ {file = "multidict-6.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd"},
+ {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3"},
+ {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf"},
+ {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29"},
+ {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed"},
+ {file = "multidict-6.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733"},
+ {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f"},
+ {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4"},
+ {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1"},
+ {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc"},
+ {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e"},
+ {file = "multidict-6.0.5-cp311-cp311-win32.whl", hash = "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c"},
+ {file = "multidict-6.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea"},
+ {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e"},
+ {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b"},
+ {file = "multidict-6.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5"},
+ {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450"},
+ {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496"},
+ {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a"},
+ {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226"},
+ {file = "multidict-6.0.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271"},
+ {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb"},
+ {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef"},
+ {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24"},
+ {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6"},
+ {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda"},
+ {file = "multidict-6.0.5-cp312-cp312-win32.whl", hash = "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5"},
+ {file = "multidict-6.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556"},
+ {file = "multidict-6.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3"},
+ {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5"},
+ {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd"},
+ {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e"},
+ {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626"},
+ {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83"},
+ {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a"},
+ {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c"},
+ {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5"},
+ {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3"},
+ {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc"},
+ {file = "multidict-6.0.5-cp37-cp37m-win32.whl", hash = "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee"},
+ {file = "multidict-6.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423"},
+ {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54"},
+ {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d"},
+ {file = "multidict-6.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7"},
+ {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93"},
+ {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8"},
+ {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b"},
+ {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50"},
+ {file = "multidict-6.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e"},
+ {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89"},
+ {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386"},
+ {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453"},
+ {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461"},
+ {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44"},
+ {file = "multidict-6.0.5-cp38-cp38-win32.whl", hash = "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241"},
+ {file = "multidict-6.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c"},
+ {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929"},
+ {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9"},
+ {file = "multidict-6.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a"},
+ {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1"},
+ {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e"},
+ {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046"},
+ {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c"},
+ {file = "multidict-6.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40"},
+ {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527"},
+ {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9"},
+ {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38"},
+ {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479"},
+ {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c"},
+ {file = "multidict-6.0.5-cp39-cp39-win32.whl", hash = "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b"},
+ {file = "multidict-6.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755"},
+ {file = "multidict-6.0.5-py3-none-any.whl", hash = "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7"},
+ {file = "multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "nb-cli"
+version = "1.3.0"
+description = "CLI for nonebot2"
+optional = false
+python-versions = "<4.0,>=3.9"
+files = [
+ {file = "nb_cli-1.3.0-py3-none-any.whl", hash = "sha256:e8346f2bc2cca873037c47738fc3203689a328d583595f8caefadebeecd5fbe4"},
+ {file = "nb_cli-1.3.0.tar.gz", hash = "sha256:cc890de5ccb35a498e413ff9deb2049c4ab9c5c73a78340a85372e2f71d6cd87"},
+]
+
+[package.dependencies]
+anyio = ">=3.6,<4.0"
+cashews = ">=6.0,<7.0"
+click = ">=8.1,<9.0"
+cookiecutter = ">=2.2,<3.0"
+httpx = ">=0.18,<1.0"
+jinja2 = ">=3.0,<4.0"
+noneprompt = ">=0.1.9,<1.0.0"
+pydantic = ">=1.9,<2.0"
+pyfiglet = ">=1.0.1,<2.0.0"
+tomlkit = ">=0.10,<1.0"
+typing-extensions = ">=4.4,<5.0"
+virtualenv = ">=20.21,<21.0"
+watchfiles = ">=0.16,<1.0"
+wcwidth = ">=0.2,<1.0"
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "nonebot-adapter-onebot"
+version = "2.4.0"
+description = "OneBot(CQHTTP) adapter for nonebot2"
+optional = false
+python-versions = ">=3.8,<4.0"
+files = [
+ {file = "nonebot_adapter_onebot-2.4.0-py3-none-any.whl", hash = "sha256:4a51da1913c8ab6008e8ef8a2877af7acc32eac82d6773ff443f743dda380e14"},
+ {file = "nonebot_adapter_onebot-2.4.0.tar.gz", hash = "sha256:27a29de8137ce60f0ea328c6fac63571ba7efef7619d0cc74c0dff42c3034b12"},
+]
+
+[package.dependencies]
+msgpack = ">=1.0.3,<2.0.0"
+nonebot2 = ">=2.2.0,<3.0.0"
+pydantic = ">=1.10.0,<2.5.0 || >2.5.0,<2.5.1 || >2.5.1,<3.0.0"
+typing-extensions = ">=4.0.0,<5.0.0"
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "nonebot-plugin-apscheduler"
+version = "0.4.0"
+description = "APScheduler Support for NoneBot2"
+optional = false
+python-versions = ">=3.8,<4.0"
+files = [
+ {file = "nonebot_plugin_apscheduler-0.4.0-py3-none-any.whl", hash = "sha256:f01bb418a5ecf9f04dcadbbc2ff5ba565a48177eb0a758c8c46b13048ac5680c"},
+ {file = "nonebot_plugin_apscheduler-0.4.0.tar.gz", hash = "sha256:ba91e68809a38e6dbe28906366d47f37f754ded360944b938cd5ac62029a0eb6"},
+]
+
+[package.dependencies]
+apscheduler = ">=3.7.0,<4.0.0"
+nonebot2 = ">=2.2.0,<3.0.0"
+pydantic = ">=1.10.0,<2.5.0 || >2.5.0,<2.5.1 || >2.5.1,<3.0.0"
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "nonebot-plugin-guild-patch"
+version = "0.2.3"
+description = "Patch plugin for NoneBot2 QQ guild (go-cqhttp) support."
+optional = false
+python-versions = ">=3.7.3,<4.0.0"
+files = [
+ {file = "nonebot_plugin_guild_patch-0.2.3-py3-none-any.whl", hash = "sha256:6dec5828e20dc7d9d72c8db6bb95623586df3cc8d54c6fc3ea9320f71995b1b8"},
+ {file = "nonebot_plugin_guild_patch-0.2.3.tar.gz", hash = "sha256:893e8dae0aef5d1fdbde841c14d59d8ef6e4555ec6339223e0f766172c97a6ee"},
+]
+
+[package.dependencies]
+nonebot-adapter-onebot = ">=2.1.0,<3.0.0"
+nonebot2 = ">=2.0.0-beta.1,<3.0.0"
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "nonebot-plugin-picmenu"
+version = "0.2"
+description = "A Plugin for Nonebot2 to generate picture menu of Plugins"
+optional = false
+python-versions = "*"
+files = [
+ {file = "nonebot_plugin_PicMenu-0.2.tar.gz", hash = "sha256:9cc5a126ccc0d2cee42759131a7616946af1747c57742ae9d11e1ce09e63ed3e"},
+]
+
+[package.dependencies]
+fuzzywuzzy = "*"
+nonebot-adapter-onebot = "*"
+nonebot2 = "*"
+pillow = "*"
+pydantic = "*"
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "nonebot-plugin-setu4"
+version = "0.13.114514"
+description = "内置数据库的setu插件, 尝试降低因为风控发不出图的概率"
+optional = false
+python-versions = ">=3.8.0"
+files = [
+ {file = "nonebot_plugin_setu4-0.13.114514-py3-none-any.whl", hash = "sha256:0eb4fc47e6e7b2911a042d6b1c3e02858682fa9e51598fea9b3458596ae2e76b"},
+ {file = "nonebot_plugin_setu4-0.13.114514.tar.gz", hash = "sha256:4bfe48dbc50a2592debae48a8d97e95080de79d4e214806890c356bb2b53ee27"},
+]
+
+[package.dependencies]
+httpx = "*"
+nonebot-adapter-onebot = "*"
+nonebot2 = "*"
+pillow = "*"
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "nonebot-plugin-weather-lite"
+version = "0.0.1"
+description = "使用wttr.in的天气查询 ,支持大部分wttr.in的用法。"
+optional = false
+python-versions = "*"
+files = [
+ {file = "nonebot_plugin_weather_lite-0.0.1-py3-none-any.whl", hash = "sha256:71940def928c625853d5da7cf983319c0c69a16c799e0514c7a5880ce5943953"},
+ {file = "nonebot_plugin_weather_lite-0.0.1.tar.gz", hash = "sha256:90a49e3dcfd4725246ca8b52209a8ed14fe7e674d5486ab052b7f44e398a8708"},
+]
+
+[package.dependencies]
+nonebot-adapter-onebot = ">=2.0.0b1"
+nonebot2 = ">=2.0.0b1"
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "nonebot2"
+version = "2.2.0"
+description = "An asynchronous python bot framework."
+optional = false
+python-versions = ">=3.8,<4.0"
+files = [
+ {file = "nonebot2-2.2.0-py3-none-any.whl", hash = "sha256:447fa63d384414c0e610f4ce6d2b3999db81ac2becd8d86716c4117013dc032f"},
+ {file = "nonebot2-2.2.0.tar.gz", hash = "sha256:138800846fa3dc635bda9f2ddc589519ee8d9d3b401013fbb95e47676fc830fb"},
+]
+
+[package.dependencies]
+fastapi = {version = ">=0.93.0,<1.0.0", optional = true, markers = "extra == \"fastapi\" or extra == \"all\""}
+loguru = ">=0.6.0,<1.0.0"
+pydantic = ">=1.10.0,<2.5.0 || >2.5.0,<2.5.1 || >2.5.1,<3.0.0"
+pygtrie = ">=2.4.1,<3.0.0"
+python-dotenv = ">=0.21.0,<2.0.0"
+tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version < \"3.11\""}
+typing-extensions = ">=4.4.0,<5.0.0"
+uvicorn = {version = ">=0.20.0,<1.0.0", extras = ["standard"], optional = true, markers = "extra == \"quart\" or extra == \"fastapi\" or extra == \"all\""}
+yarl = ">=1.7.2,<2.0.0"
+
+[package.extras]
+aiohttp = ["aiohttp[speedups] (>=3.9.0b0,<4.0.0)"]
+all = ["Quart (>=0.18.0,<1.0.0)", "aiohttp[speedups] (>=3.9.0b0,<4.0.0)", "fastapi (>=0.93.0,<1.0.0)", "httpx[http2] (>=0.20.0,<1.0.0)", "uvicorn[standard] (>=0.20.0,<1.0.0)", "websockets (>=10.0)"]
+fastapi = ["fastapi (>=0.93.0,<1.0.0)", "uvicorn[standard] (>=0.20.0,<1.0.0)"]
+httpx = ["httpx[http2] (>=0.20.0,<1.0.0)"]
+quart = ["Quart (>=0.18.0,<1.0.0)", "uvicorn[standard] (>=0.20.0,<1.0.0)"]
+websockets = ["websockets (>=10.0)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "noneprompt"
+version = "0.1.9"
+description = "Prompt toolkit for console interaction"
+optional = false
+python-versions = ">=3.8,<4.0"
+files = [
+ {file = "noneprompt-0.1.9-py3-none-any.whl", hash = "sha256:a54f1e6a19a3da2dedf7f365f80420e9ae49326a0ffe60a8a9c7afdee6b6eeb3"},
+ {file = "noneprompt-0.1.9.tar.gz", hash = "sha256:338b8bb89a8d22ef35f1dedb3aa7c1b228cf139973bdc43c5ffc3eef64457db9"},
+]
+
+[package.dependencies]
+prompt-toolkit = ">=3.0.19,<4.0.0"
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "pillow"
+version = "10.2.0"
+description = "Python Imaging Library (Fork)"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "pillow-10.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:7823bdd049099efa16e4246bdf15e5a13dbb18a51b68fa06d6c1d4d8b99a796e"},
+ {file = "pillow-10.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:83b2021f2ade7d1ed556bc50a399127d7fb245e725aa0113ebd05cfe88aaf588"},
+ {file = "pillow-10.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fad5ff2f13d69b7e74ce5b4ecd12cc0ec530fcee76356cac6742785ff71c452"},
+ {file = "pillow-10.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da2b52b37dad6d9ec64e653637a096905b258d2fc2b984c41ae7d08b938a67e4"},
+ {file = "pillow-10.2.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:47c0995fc4e7f79b5cfcab1fc437ff2890b770440f7696a3ba065ee0fd496563"},
+ {file = "pillow-10.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:322bdf3c9b556e9ffb18f93462e5f749d3444ce081290352c6070d014c93feb2"},
+ {file = "pillow-10.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:51f1a1bffc50e2e9492e87d8e09a17c5eea8409cda8d3f277eb6edc82813c17c"},
+ {file = "pillow-10.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69ffdd6120a4737710a9eee73e1d2e37db89b620f702754b8f6e62594471dee0"},
+ {file = "pillow-10.2.0-cp310-cp310-win32.whl", hash = "sha256:c6dafac9e0f2b3c78df97e79af707cdc5ef8e88208d686a4847bab8266870023"},
+ {file = "pillow-10.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:aebb6044806f2e16ecc07b2a2637ee1ef67a11840a66752751714a0d924adf72"},
+ {file = "pillow-10.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:7049e301399273a0136ff39b84c3678e314f2158f50f517bc50285fb5ec847ad"},
+ {file = "pillow-10.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:35bb52c37f256f662abdfa49d2dfa6ce5d93281d323a9af377a120e89a9eafb5"},
+ {file = "pillow-10.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c23f307202661071d94b5e384e1e1dc7dfb972a28a2310e4ee16103e66ddb67"},
+ {file = "pillow-10.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:773efe0603db30c281521a7c0214cad7836c03b8ccff897beae9b47c0b657d61"},
+ {file = "pillow-10.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11fa2e5984b949b0dd6d7a94d967743d87c577ff0b83392f17cb3990d0d2fd6e"},
+ {file = "pillow-10.2.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:716d30ed977be8b37d3ef185fecb9e5a1d62d110dfbdcd1e2a122ab46fddb03f"},
+ {file = "pillow-10.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a086c2af425c5f62a65e12fbf385f7c9fcb8f107d0849dba5839461a129cf311"},
+ {file = "pillow-10.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c8de2789052ed501dd829e9cae8d3dcce7acb4777ea4a479c14521c942d395b1"},
+ {file = "pillow-10.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:609448742444d9290fd687940ac0b57fb35e6fd92bdb65386e08e99af60bf757"},
+ {file = "pillow-10.2.0-cp311-cp311-win32.whl", hash = "sha256:823ef7a27cf86df6597fa0671066c1b596f69eba53efa3d1e1cb8b30f3533068"},
+ {file = "pillow-10.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:1da3b2703afd040cf65ec97efea81cfba59cdbed9c11d8efc5ab09df9509fc56"},
+ {file = "pillow-10.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:edca80cbfb2b68d7b56930b84a0e45ae1694aeba0541f798e908a49d66b837f1"},
+ {file = "pillow-10.2.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:1b5e1b74d1bd1b78bc3477528919414874748dd363e6272efd5abf7654e68bef"},
+ {file = "pillow-10.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0eae2073305f451d8ecacb5474997c08569fb4eb4ac231ffa4ad7d342fdc25ac"},
+ {file = "pillow-10.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7c2286c23cd350b80d2fc9d424fc797575fb16f854b831d16fd47ceec078f2c"},
+ {file = "pillow-10.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e23412b5c41e58cec602f1135c57dfcf15482013ce6e5f093a86db69646a5aa"},
+ {file = "pillow-10.2.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:52a50aa3fb3acb9cf7213573ef55d31d6eca37f5709c69e6858fe3bc04a5c2a2"},
+ {file = "pillow-10.2.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:127cee571038f252a552760076407f9cff79761c3d436a12af6000cd182a9d04"},
+ {file = "pillow-10.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8d12251f02d69d8310b046e82572ed486685c38f02176bd08baf216746eb947f"},
+ {file = "pillow-10.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:54f1852cd531aa981bc0965b7d609f5f6cc8ce8c41b1139f6ed6b3c54ab82bfb"},
+ {file = "pillow-10.2.0-cp312-cp312-win32.whl", hash = "sha256:257d8788df5ca62c980314053197f4d46eefedf4e6175bc9412f14412ec4ea2f"},
+ {file = "pillow-10.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:154e939c5f0053a383de4fd3d3da48d9427a7e985f58af8e94d0b3c9fcfcf4f9"},
+ {file = "pillow-10.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:f379abd2f1e3dddb2b61bc67977a6b5a0a3f7485538bcc6f39ec76163891ee48"},
+ {file = "pillow-10.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8373c6c251f7ef8bda6675dd6d2b3a0fcc31edf1201266b5cf608b62a37407f9"},
+ {file = "pillow-10.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:870ea1ada0899fd0b79643990809323b389d4d1d46c192f97342eeb6ee0b8483"},
+ {file = "pillow-10.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4b6b1e20608493548b1f32bce8cca185bf0480983890403d3b8753e44077129"},
+ {file = "pillow-10.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3031709084b6e7852d00479fd1d310b07d0ba82765f973b543c8af5061cf990e"},
+ {file = "pillow-10.2.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:3ff074fc97dd4e80543a3e91f69d58889baf2002b6be64347ea8cf5533188213"},
+ {file = "pillow-10.2.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:cb4c38abeef13c61d6916f264d4845fab99d7b711be96c326b84df9e3e0ff62d"},
+ {file = "pillow-10.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b1b3020d90c2d8e1dae29cf3ce54f8094f7938460fb5ce8bc5c01450b01fbaf6"},
+ {file = "pillow-10.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:170aeb00224ab3dc54230c797f8404507240dd868cf52066f66a41b33169bdbe"},
+ {file = "pillow-10.2.0-cp38-cp38-win32.whl", hash = "sha256:c4225f5220f46b2fde568c74fca27ae9771536c2e29d7c04f4fb62c83275ac4e"},
+ {file = "pillow-10.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:0689b5a8c5288bc0504d9fcee48f61a6a586b9b98514d7d29b840143d6734f39"},
+ {file = "pillow-10.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:b792a349405fbc0163190fde0dc7b3fef3c9268292586cf5645598b48e63dc67"},
+ {file = "pillow-10.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c570f24be1e468e3f0ce7ef56a89a60f0e05b30a3669a459e419c6eac2c35364"},
+ {file = "pillow-10.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8ecd059fdaf60c1963c58ceb8997b32e9dc1b911f5da5307aab614f1ce5c2fb"},
+ {file = "pillow-10.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c365fd1703040de1ec284b176d6af5abe21b427cb3a5ff68e0759e1e313a5e7e"},
+ {file = "pillow-10.2.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:70c61d4c475835a19b3a5aa42492409878bbca7438554a1f89d20d58a7c75c01"},
+ {file = "pillow-10.2.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b6f491cdf80ae540738859d9766783e3b3c8e5bd37f5dfa0b76abdecc5081f13"},
+ {file = "pillow-10.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d189550615b4948f45252d7f005e53c2040cea1af5b60d6f79491a6e147eef7"},
+ {file = "pillow-10.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:49d9ba1ed0ef3e061088cd1e7538a0759aab559e2e0a80a36f9fd9d8c0c21591"},
+ {file = "pillow-10.2.0-cp39-cp39-win32.whl", hash = "sha256:babf5acfede515f176833ed6028754cbcd0d206f7f614ea3447d67c33be12516"},
+ {file = "pillow-10.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:0304004f8067386b477d20a518b50f3fa658a28d44e4116970abfcd94fac34a8"},
+ {file = "pillow-10.2.0-cp39-cp39-win_arm64.whl", hash = "sha256:0fb3e7fc88a14eacd303e90481ad983fd5b69c761e9e6ef94c983f91025da869"},
+ {file = "pillow-10.2.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:322209c642aabdd6207517e9739c704dc9f9db943015535783239022002f054a"},
+ {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eedd52442c0a5ff4f887fab0c1c0bb164d8635b32c894bc1faf4c618dd89df2"},
+ {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb28c753fd5eb3dd859b4ee95de66cc62af91bcff5db5f2571d32a520baf1f04"},
+ {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:33870dc4653c5017bf4c8873e5488d8f8d5f8935e2f1fb9a2208c47cdd66efd2"},
+ {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3c31822339516fb3c82d03f30e22b1d038da87ef27b6a78c9549888f8ceda39a"},
+ {file = "pillow-10.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a2b56ba36e05f973d450582fb015594aaa78834fefe8dfb8fcd79b93e64ba4c6"},
+ {file = "pillow-10.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d8e6aeb9201e655354b3ad049cb77d19813ad4ece0df1249d3c793de3774f8c7"},
+ {file = "pillow-10.2.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:2247178effb34a77c11c0e8ac355c7a741ceca0a732b27bf11e747bbc950722f"},
+ {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15587643b9e5eb26c48e49a7b33659790d28f190fc514a322d55da2fb5c2950e"},
+ {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753cd8f2086b2b80180d9b3010dd4ed147efc167c90d3bf593fe2af21265e5a5"},
+ {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7c8f97e8e7a9009bcacbe3766a36175056c12f9a44e6e6f2d5caad06dcfbf03b"},
+ {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d1b35bcd6c5543b9cb547dee3150c93008f8dd0f1fef78fc0cd2b141c5baf58a"},
+ {file = "pillow-10.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fe4c15f6c9285dc54ce6553a3ce908ed37c8f3825b5a51a15c91442bb955b868"},
+ {file = "pillow-10.2.0.tar.gz", hash = "sha256:e87f0b2c78157e12d7686b27d63c070fd65d994e8ddae6f328e0dcf4a0cd007e"},
+]
+
+[package.extras]
+docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"]
+fpx = ["olefile"]
+mic = ["olefile"]
+tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"]
+typing = ["typing-extensions"]
+xmp = ["defusedxml"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "platformdirs"
+version = "4.2.0"
+description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"},
+ {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"},
+]
+
+[package.extras]
+docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "prompt-toolkit"
+version = "3.0.43"
+description = "Library for building powerful interactive command lines in Python"
+optional = false
+python-versions = ">=3.7.0"
+files = [
+ {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"},
+ {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"},
+]
+
+[package.dependencies]
+wcwidth = "*"
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "pydantic"
+version = "1.10.14"
+description = "Data validation and settings management using python type hints"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "pydantic-1.10.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f4fcec873f90537c382840f330b90f4715eebc2bc9925f04cb92de593eae054"},
+ {file = "pydantic-1.10.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e3a76f571970fcd3c43ad982daf936ae39b3e90b8a2e96c04113a369869dc87"},
+ {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d886bd3c3fbeaa963692ef6b643159ccb4b4cefaf7ff1617720cbead04fd1d"},
+ {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:798a3d05ee3b71967844a1164fd5bdb8c22c6d674f26274e78b9f29d81770c4e"},
+ {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:23d47a4b57a38e8652bcab15a658fdb13c785b9ce217cc3a729504ab4e1d6bc9"},
+ {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9f674b5c3bebc2eba401de64f29948ae1e646ba2735f884d1594c5f675d6f2a"},
+ {file = "pydantic-1.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:24a7679fab2e0eeedb5a8924fc4a694b3bcaac7d305aeeac72dd7d4e05ecbebf"},
+ {file = "pydantic-1.10.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d578ac4bf7fdf10ce14caba6f734c178379bd35c486c6deb6f49006e1ba78a7"},
+ {file = "pydantic-1.10.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa7790e94c60f809c95602a26d906eba01a0abee9cc24150e4ce2189352deb1b"},
+ {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad4e10efa5474ed1a611b6d7f0d130f4aafadceb73c11d9e72823e8f508e663"},
+ {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1245f4f61f467cb3dfeced2b119afef3db386aec3d24a22a1de08c65038b255f"},
+ {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:21efacc678a11114c765eb52ec0db62edffa89e9a562a94cbf8fa10b5db5c046"},
+ {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:412ab4a3f6dbd2bf18aefa9f79c7cca23744846b31f1d6555c2ee2b05a2e14ca"},
+ {file = "pydantic-1.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:e897c9f35281f7889873a3e6d6b69aa1447ceb024e8495a5f0d02ecd17742a7f"},
+ {file = "pydantic-1.10.14-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d604be0f0b44d473e54fdcb12302495fe0467c56509a2f80483476f3ba92b33c"},
+ {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42c7d17706911199798d4c464b352e640cab4351efe69c2267823d619a937e5"},
+ {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:596f12a1085e38dbda5cbb874d0973303e34227b400b6414782bf205cc14940c"},
+ {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bfb113860e9288d0886e3b9e49d9cf4a9d48b441f52ded7d96db7819028514cc"},
+ {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bc3ed06ab13660b565eed80887fcfbc0070f0aa0691fbb351657041d3e874efe"},
+ {file = "pydantic-1.10.14-cp37-cp37m-win_amd64.whl", hash = "sha256:ad8c2bc677ae5f6dbd3cf92f2c7dc613507eafe8f71719727cbc0a7dec9a8c01"},
+ {file = "pydantic-1.10.14-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c37c28449752bb1f47975d22ef2882d70513c546f8f37201e0fec3a97b816eee"},
+ {file = "pydantic-1.10.14-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49a46a0994dd551ec051986806122767cf144b9702e31d47f6d493c336462597"},
+ {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53e3819bd20a42470d6dd0fe7fc1c121c92247bca104ce608e609b59bc7a77ee"},
+ {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbb503bbbbab0c588ed3cd21975a1d0d4163b87e360fec17a792f7d8c4ff29f"},
+ {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:336709883c15c050b9c55a63d6c7ff09be883dbc17805d2b063395dd9d9d0022"},
+ {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4ae57b4d8e3312d486e2498d42aed3ece7b51848336964e43abbf9671584e67f"},
+ {file = "pydantic-1.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:dba49d52500c35cfec0b28aa8b3ea5c37c9df183ffc7210b10ff2a415c125c4a"},
+ {file = "pydantic-1.10.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c66609e138c31cba607d8e2a7b6a5dc38979a06c900815495b2d90ce6ded35b4"},
+ {file = "pydantic-1.10.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d986e115e0b39604b9eee3507987368ff8148222da213cd38c359f6f57b3b347"},
+ {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:646b2b12df4295b4c3148850c85bff29ef6d0d9621a8d091e98094871a62e5c7"},
+ {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282613a5969c47c83a8710cc8bfd1e70c9223feb76566f74683af889faadc0ea"},
+ {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:466669501d08ad8eb3c4fecd991c5e793c4e0bbd62299d05111d4f827cded64f"},
+ {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:13e86a19dca96373dcf3190fcb8797d40a6f12f154a244a8d1e8e03b8f280593"},
+ {file = "pydantic-1.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:08b6ec0917c30861e3fe71a93be1648a2aa4f62f866142ba21670b24444d7fd8"},
+ {file = "pydantic-1.10.14-py3-none-any.whl", hash = "sha256:8ee853cd12ac2ddbf0ecbac1c289f95882b2d4482258048079d13be700aa114c"},
+ {file = "pydantic-1.10.14.tar.gz", hash = "sha256:46f17b832fe27de7850896f3afee50ea682220dd218f7e9c88d436788419dca6"},
+]
+
+[package.dependencies]
+typing-extensions = ">=4.2.0"
+
+[package.extras]
+dotenv = ["python-dotenv (>=0.10.4)"]
+email = ["email-validator (>=1.0.3)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "pyfiglet"
+version = "1.0.2"
+description = "Pure-python FIGlet implementation"
+optional = false
+python-versions = ">=3.9"
+files = [
+ {file = "pyfiglet-1.0.2-py3-none-any.whl", hash = "sha256:889b351d79c99e50a3f619c8f8e6ffdb27fd8c939fc43ecbd7559bd57d5f93ea"},
+ {file = "pyfiglet-1.0.2.tar.gz", hash = "sha256:758788018ab8faaddc0984e1ea05ff330d3c64be663c513cc1f105f6a3066dab"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "pygments"
+version = "2.17.2"
+description = "Pygments is a syntax highlighting package written in Python."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"},
+ {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"},
+]
+
+[package.extras]
+plugins = ["importlib-metadata"]
+windows-terminal = ["colorama (>=0.4.6)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "pygtrie"
+version = "2.5.0"
+description = "A pure Python trie data structure implementation."
+optional = false
+python-versions = "*"
+files = [
+ {file = "pygtrie-2.5.0-py3-none-any.whl", hash = "sha256:8795cda8105493d5ae159a5bef313ff13156c5d4d72feddefacaad59f8c8ce16"},
+ {file = "pygtrie-2.5.0.tar.gz", hash = "sha256:203514ad826eb403dab1d2e2ddd034e0d1534bbe4dbe0213bb0593f66beba4e2"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "python-dateutil"
+version = "2.8.2"
+description = "Extensions to the standard Python datetime module"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
+files = [
+ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
+ {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
+]
+
+[package.dependencies]
+six = ">=1.5"
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "python-dotenv"
+version = "1.0.1"
+description = "Read key-value pairs from a .env file and set them as environment variables"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"},
+ {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"},
+]
+
+[package.extras]
+cli = ["click (>=5.0)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "python-slugify"
+version = "8.0.4"
+description = "A Python slugify application that also handles Unicode"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856"},
+ {file = "python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8"},
+]
+
+[package.dependencies]
+text-unidecode = ">=1.3"
+
+[package.extras]
+unidecode = ["Unidecode (>=1.1.1)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "pytz"
+version = "2024.1"
+description = "World timezone definitions, modern and historical"
+optional = false
+python-versions = "*"
+files = [
+ {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"},
+ {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "pyyaml"
+version = "6.0.1"
+description = "YAML parser and emitter for Python"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
+ {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
+ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
+ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
+ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
+ {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
+ {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
+ {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
+ {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
+ {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
+ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
+ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
+ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
+ {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
+ {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
+ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
+ {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
+ {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
+ {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
+ {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
+ {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
+ {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
+ {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
+ {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
+ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
+ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
+ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
+ {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
+ {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
+ {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
+ {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
+ {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
+ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
+ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
+ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
+ {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
+ {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
+ {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
+ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "requests"
+version = "2.31.0"
+description = "Python HTTP for Humans."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
+ {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
+]
+
+[package.dependencies]
+certifi = ">=2017.4.17"
+charset-normalizer = ">=2,<4"
+idna = ">=2.5,<4"
+urllib3 = ">=1.21.1,<3"
+
+[package.extras]
+socks = ["PySocks (>=1.5.6,!=1.5.7)"]
+use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "rich"
+version = "13.7.0"
+description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
+optional = false
+python-versions = ">=3.7.0"
+files = [
+ {file = "rich-13.7.0-py3-none-any.whl", hash = "sha256:6da14c108c4866ee9520bbffa71f6fe3962e193b7da68720583850cd4548e235"},
+ {file = "rich-13.7.0.tar.gz", hash = "sha256:5cb5123b5cf9ee70584244246816e9114227e0b98ad9176eede6ad54bf5403fa"},
+]
+
+[package.dependencies]
+markdown-it-py = ">=2.2.0"
+pygments = ">=2.13.0,<3.0.0"
+
+[package.extras]
+jupyter = ["ipywidgets (>=7.5.1,<9)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "six"
+version = "1.16.0"
+description = "Python 2 and 3 compatibility utilities"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
+files = [
+ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
+ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "sniffio"
+version = "1.3.0"
+description = "Sniff out which async library your code is running under"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"},
+ {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "starlette"
+version = "0.36.3"
+description = "The little ASGI library that shines."
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "starlette-0.36.3-py3-none-any.whl", hash = "sha256:13d429aa93a61dc40bf503e8c801db1f1bca3dc706b10ef2434a36123568f044"},
+ {file = "starlette-0.36.3.tar.gz", hash = "sha256:90a671733cfb35771d8cc605e0b679d23b992f8dcfad48cc60b38cb29aeb7080"},
+]
+
+[package.dependencies]
+anyio = ">=3.4.0,<5"
+
+[package.extras]
+full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "text-unidecode"
+version = "1.3"
+description = "The most basic Text::Unidecode port"
+optional = false
+python-versions = "*"
+files = [
+ {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"},
+ {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "tomli"
+version = "2.0.1"
+description = "A lil' TOML parser"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
+ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "tomlkit"
+version = "0.12.3"
+description = "Style preserving TOML library"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "tomlkit-0.12.3-py3-none-any.whl", hash = "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba"},
+ {file = "tomlkit-0.12.3.tar.gz", hash = "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "types-python-dateutil"
+version = "2.8.19.20240106"
+description = "Typing stubs for python-dateutil"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "types-python-dateutil-2.8.19.20240106.tar.gz", hash = "sha256:1f8db221c3b98e6ca02ea83a58371b22c374f42ae5bbdf186db9c9a76581459f"},
+ {file = "types_python_dateutil-2.8.19.20240106-py3-none-any.whl", hash = "sha256:efbbdc54590d0f16152fa103c9879c7d4a00e82078f6e2cf01769042165acaa2"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "typing-extensions"
+version = "4.9.0"
+description = "Backported and Experimental Type Hints for Python 3.8+"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"},
+ {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "tzdata"
+version = "2024.1"
+description = "Provider of IANA time zone data"
+optional = false
+python-versions = ">=2"
+files = [
+ {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"},
+ {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "tzlocal"
+version = "5.2"
+description = "tzinfo object for the local timezone"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"},
+ {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"},
+]
+
+[package.dependencies]
+tzdata = {version = "*", markers = "platform_system == \"Windows\""}
+
+[package.extras]
+devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3)", "zest.releaser"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "urllib3"
+version = "2.2.0"
+description = "HTTP library with thread-safe connection pooling, file post, and more."
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "urllib3-2.2.0-py3-none-any.whl", hash = "sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224"},
+ {file = "urllib3-2.2.0.tar.gz", hash = "sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20"},
+]
+
+[package.extras]
+brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
+h2 = ["h2 (>=4,<5)"]
+socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
+zstd = ["zstandard (>=0.18.0)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "uvicorn"
+version = "0.27.1"
+description = "The lightning-fast ASGI server."
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "uvicorn-0.27.1-py3-none-any.whl", hash = "sha256:5c89da2f3895767472a35556e539fd59f7edbe9b1e9c0e1c99eebeadc61838e4"},
+ {file = "uvicorn-0.27.1.tar.gz", hash = "sha256:3d9a267296243532db80c83a959a3400502165ade2c1338dea4e67915fd4745a"},
+]
+
+[package.dependencies]
+click = ">=7.0"
+colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""}
+h11 = ">=0.8"
+httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""}
+python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
+pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
+typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""}
+uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
+watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
+websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""}
+
+[package.extras]
+standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "uvloop"
+version = "0.19.0"
+description = "Fast implementation of asyncio event loop on top of libuv"
+optional = false
+python-versions = ">=3.8.0"
+files = [
+ {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e"},
+ {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428"},
+ {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8"},
+ {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849"},
+ {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957"},
+ {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd"},
+ {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef"},
+ {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2"},
+ {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1"},
+ {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24"},
+ {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533"},
+ {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12"},
+ {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650"},
+ {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec"},
+ {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc"},
+ {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6"},
+ {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593"},
+ {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3"},
+ {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd"},
+ {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd"},
+ {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be"},
+ {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797"},
+ {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d"},
+ {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7"},
+ {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b"},
+ {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67"},
+ {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7"},
+ {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256"},
+ {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17"},
+ {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5"},
+ {file = "uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd"},
+]
+
+[package.extras]
+docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"]
+test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)", "flake8 (>=5.0,<6.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=23.0.0,<23.1.0)", "pycodestyle (>=2.9.0,<2.10.0)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "virtualenv"
+version = "20.25.0"
+description = "Virtual Python Environment builder"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "virtualenv-20.25.0-py3-none-any.whl", hash = "sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3"},
+ {file = "virtualenv-20.25.0.tar.gz", hash = "sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b"},
+]
+
+[package.dependencies]
+distlib = ">=0.3.7,<1"
+filelock = ">=3.12.2,<4"
+platformdirs = ">=3.9.1,<5"
+
+[package.extras]
+docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
+test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "watchfiles"
+version = "0.21.0"
+description = "Simple, modern and high performance file watching and code reload in python."
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "watchfiles-0.21.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:27b4035013f1ea49c6c0b42d983133b136637a527e48c132d368eb19bf1ac6aa"},
+ {file = "watchfiles-0.21.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c81818595eff6e92535ff32825f31c116f867f64ff8cdf6562cd1d6b2e1e8f3e"},
+ {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6c107ea3cf2bd07199d66f156e3ea756d1b84dfd43b542b2d870b77868c98c03"},
+ {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d9ac347653ebd95839a7c607608703b20bc07e577e870d824fa4801bc1cb124"},
+ {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5eb86c6acb498208e7663ca22dbe68ca2cf42ab5bf1c776670a50919a56e64ab"},
+ {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f564bf68404144ea6b87a78a3f910cc8de216c6b12a4cf0b27718bf4ec38d303"},
+ {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d0f32ebfaa9c6011f8454994f86108c2eb9c79b8b7de00b36d558cadcedaa3d"},
+ {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d45d9b699ecbac6c7bd8e0a2609767491540403610962968d258fd6405c17c"},
+ {file = "watchfiles-0.21.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:aff06b2cac3ef4616e26ba17a9c250c1fe9dd8a5d907d0193f84c499b1b6e6a9"},
+ {file = "watchfiles-0.21.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d9792dff410f266051025ecfaa927078b94cc7478954b06796a9756ccc7e14a9"},
+ {file = "watchfiles-0.21.0-cp310-none-win32.whl", hash = "sha256:214cee7f9e09150d4fb42e24919a1e74d8c9b8a9306ed1474ecaddcd5479c293"},
+ {file = "watchfiles-0.21.0-cp310-none-win_amd64.whl", hash = "sha256:1ad7247d79f9f55bb25ab1778fd47f32d70cf36053941f07de0b7c4e96b5d235"},
+ {file = "watchfiles-0.21.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:668c265d90de8ae914f860d3eeb164534ba2e836811f91fecc7050416ee70aa7"},
+ {file = "watchfiles-0.21.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a23092a992e61c3a6a70f350a56db7197242f3490da9c87b500f389b2d01eef"},
+ {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e7941bbcfdded9c26b0bf720cb7e6fd803d95a55d2c14b4bd1f6a2772230c586"},
+ {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11cd0c3100e2233e9c53106265da31d574355c288e15259c0d40a4405cbae317"},
+ {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78f30cbe8b2ce770160d3c08cff01b2ae9306fe66ce899b73f0409dc1846c1b"},
+ {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6674b00b9756b0af620aa2a3346b01f8e2a3dc729d25617e1b89cf6af4a54eb1"},
+ {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd7ac678b92b29ba630d8c842d8ad6c555abda1b9ef044d6cc092dacbfc9719d"},
+ {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c873345680c1b87f1e09e0eaf8cf6c891b9851d8b4d3645e7efe2ec20a20cc7"},
+ {file = "watchfiles-0.21.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49f56e6ecc2503e7dbe233fa328b2be1a7797d31548e7a193237dcdf1ad0eee0"},
+ {file = "watchfiles-0.21.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:02d91cbac553a3ad141db016e3350b03184deaafeba09b9d6439826ee594b365"},
+ {file = "watchfiles-0.21.0-cp311-none-win32.whl", hash = "sha256:ebe684d7d26239e23d102a2bad2a358dedf18e462e8808778703427d1f584400"},
+ {file = "watchfiles-0.21.0-cp311-none-win_amd64.whl", hash = "sha256:4566006aa44cb0d21b8ab53baf4b9c667a0ed23efe4aaad8c227bfba0bf15cbe"},
+ {file = "watchfiles-0.21.0-cp311-none-win_arm64.whl", hash = "sha256:c550a56bf209a3d987d5a975cdf2063b3389a5d16caf29db4bdddeae49f22078"},
+ {file = "watchfiles-0.21.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:51ddac60b96a42c15d24fbdc7a4bfcd02b5a29c047b7f8bf63d3f6f5a860949a"},
+ {file = "watchfiles-0.21.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:511f0b034120cd1989932bf1e9081aa9fb00f1f949fbd2d9cab6264916ae89b1"},
+ {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cfb92d49dbb95ec7a07511bc9efb0faff8fe24ef3805662b8d6808ba8409a71a"},
+ {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f92944efc564867bbf841c823c8b71bb0be75e06b8ce45c084b46411475a915"},
+ {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:642d66b75eda909fd1112d35c53816d59789a4b38c141a96d62f50a3ef9b3360"},
+ {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d23bcd6c8eaa6324fe109d8cac01b41fe9a54b8c498af9ce464c1aeeb99903d6"},
+ {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18d5b4da8cf3e41895b34e8c37d13c9ed294954907929aacd95153508d5d89d7"},
+ {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b8d1eae0f65441963d805f766c7e9cd092f91e0c600c820c764a4ff71a0764c"},
+ {file = "watchfiles-0.21.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1fd9a5205139f3c6bb60d11f6072e0552f0a20b712c85f43d42342d162be1235"},
+ {file = "watchfiles-0.21.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a1e3014a625bcf107fbf38eece0e47fa0190e52e45dc6eee5a8265ddc6dc5ea7"},
+ {file = "watchfiles-0.21.0-cp312-none-win32.whl", hash = "sha256:9d09869f2c5a6f2d9df50ce3064b3391d3ecb6dced708ad64467b9e4f2c9bef3"},
+ {file = "watchfiles-0.21.0-cp312-none-win_amd64.whl", hash = "sha256:18722b50783b5e30a18a8a5db3006bab146d2b705c92eb9a94f78c72beb94094"},
+ {file = "watchfiles-0.21.0-cp312-none-win_arm64.whl", hash = "sha256:a3b9bec9579a15fb3ca2d9878deae789df72f2b0fdaf90ad49ee389cad5edab6"},
+ {file = "watchfiles-0.21.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:4ea10a29aa5de67de02256a28d1bf53d21322295cb00bd2d57fcd19b850ebd99"},
+ {file = "watchfiles-0.21.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:40bca549fdc929b470dd1dbfcb47b3295cb46a6d2c90e50588b0a1b3bd98f429"},
+ {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9b37a7ba223b2f26122c148bb8d09a9ff312afca998c48c725ff5a0a632145f7"},
+ {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec8c8900dc5c83650a63dd48c4d1d245343f904c4b64b48798c67a3767d7e165"},
+ {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ad3fe0a3567c2f0f629d800409cd528cb6251da12e81a1f765e5c5345fd0137"},
+ {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d353c4cfda586db2a176ce42c88f2fc31ec25e50212650c89fdd0f560ee507b"},
+ {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:83a696da8922314ff2aec02987eefb03784f473281d740bf9170181829133765"},
+ {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a03651352fc20975ee2a707cd2d74a386cd303cc688f407296064ad1e6d1562"},
+ {file = "watchfiles-0.21.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3ad692bc7792be8c32918c699638b660c0de078a6cbe464c46e1340dadb94c19"},
+ {file = "watchfiles-0.21.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06247538e8253975bdb328e7683f8515ff5ff041f43be6c40bff62d989b7d0b0"},
+ {file = "watchfiles-0.21.0-cp38-none-win32.whl", hash = "sha256:9a0aa47f94ea9a0b39dd30850b0adf2e1cd32a8b4f9c7aa443d852aacf9ca214"},
+ {file = "watchfiles-0.21.0-cp38-none-win_amd64.whl", hash = "sha256:8d5f400326840934e3507701f9f7269247f7c026d1b6cfd49477d2be0933cfca"},
+ {file = "watchfiles-0.21.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:7f762a1a85a12cc3484f77eee7be87b10f8c50b0b787bb02f4e357403cad0c0e"},
+ {file = "watchfiles-0.21.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6e9be3ef84e2bb9710f3f777accce25556f4a71e15d2b73223788d528fcc2052"},
+ {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4c48a10d17571d1275701e14a601e36959ffada3add8cdbc9e5061a6e3579a5d"},
+ {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c889025f59884423428c261f212e04d438de865beda0b1e1babab85ef4c0f01"},
+ {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:66fac0c238ab9a2e72d026b5fb91cb902c146202bbd29a9a1a44e8db7b710b6f"},
+ {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4a21f71885aa2744719459951819e7bf5a906a6448a6b2bbce8e9cc9f2c8128"},
+ {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c9198c989f47898b2c22201756f73249de3748e0fc9de44adaf54a8b259cc0c"},
+ {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f57c4461cd24fda22493109c45b3980863c58a25b8bec885ca8bea6b8d4b28"},
+ {file = "watchfiles-0.21.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:853853cbf7bf9408b404754b92512ebe3e3a83587503d766d23e6bf83d092ee6"},
+ {file = "watchfiles-0.21.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d5b1dc0e708fad9f92c296ab2f948af403bf201db8fb2eb4c8179db143732e49"},
+ {file = "watchfiles-0.21.0-cp39-none-win32.whl", hash = "sha256:59137c0c6826bd56c710d1d2bda81553b5e6b7c84d5a676747d80caf0409ad94"},
+ {file = "watchfiles-0.21.0-cp39-none-win_amd64.whl", hash = "sha256:6cb8fdc044909e2078c248986f2fc76f911f72b51ea4a4fbbf472e01d14faa58"},
+ {file = "watchfiles-0.21.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab03a90b305d2588e8352168e8c5a1520b721d2d367f31e9332c4235b30b8994"},
+ {file = "watchfiles-0.21.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:927c589500f9f41e370b0125c12ac9e7d3a2fd166b89e9ee2828b3dda20bfe6f"},
+ {file = "watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd467213195e76f838caf2c28cd65e58302d0254e636e7c0fca81efa4a2e62c"},
+ {file = "watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02b73130687bc3f6bb79d8a170959042eb56eb3a42df3671c79b428cd73f17cc"},
+ {file = "watchfiles-0.21.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:08dca260e85ffae975448e344834d765983237ad6dc308231aa16e7933db763e"},
+ {file = "watchfiles-0.21.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:3ccceb50c611c433145502735e0370877cced72a6c70fd2410238bcbc7fe51d8"},
+ {file = "watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57d430f5fb63fea141ab71ca9c064e80de3a20b427ca2febcbfcef70ff0ce895"},
+ {file = "watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dd5fad9b9c0dd89904bbdea978ce89a2b692a7ee8a0ce19b940e538c88a809c"},
+ {file = "watchfiles-0.21.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:be6dd5d52b73018b21adc1c5d28ac0c68184a64769052dfeb0c5d9998e7f56a2"},
+ {file = "watchfiles-0.21.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b3cab0e06143768499384a8a5efb9c4dc53e19382952859e4802f294214f36ec"},
+ {file = "watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c6ed10c2497e5fedadf61e465b3ca12a19f96004c15dcffe4bd442ebadc2d85"},
+ {file = "watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43babacef21c519bc6631c5fce2a61eccdfc011b4bcb9047255e9620732c8097"},
+ {file = "watchfiles-0.21.0.tar.gz", hash = "sha256:c76c635fabf542bb78524905718c39f736a98e5ab25b23ec6d4abede1a85a6a3"},
+]
+
+[package.dependencies]
+anyio = ">=3.0.0"
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "wcwidth"
+version = "0.2.13"
+description = "Measures the displayed width of unicode strings in a terminal"
+optional = false
+python-versions = "*"
+files = [
+ {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"},
+ {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "websockets"
+version = "12.0"
+description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"},
+ {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"},
+ {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"},
+ {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"},
+ {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"},
+ {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"},
+ {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"},
+ {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"},
+ {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"},
+ {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"},
+ {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"},
+ {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"},
+ {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"},
+ {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"},
+ {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"},
+ {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"},
+ {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"},
+ {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"},
+ {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"},
+ {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"},
+ {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"},
+ {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"},
+ {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"},
+ {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"},
+ {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"},
+ {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"},
+ {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"},
+ {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"},
+ {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"},
+ {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"},
+ {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"},
+ {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"},
+ {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"},
+ {file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"},
+ {file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"},
+ {file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"},
+ {file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"},
+ {file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"},
+ {file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"},
+ {file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"},
+ {file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"},
+ {file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"},
+ {file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"},
+ {file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"},
+ {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"},
+ {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"},
+ {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"},
+ {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"},
+ {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"},
+ {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"},
+ {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"},
+ {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"},
+ {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"},
+ {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"},
+ {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"},
+ {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"},
+ {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"},
+ {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"},
+ {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"},
+ {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"},
+ {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"},
+ {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"},
+ {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"},
+ {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"},
+ {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"},
+ {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"},
+ {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"},
+ {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"},
+ {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"},
+ {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"},
+ {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"},
+ {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"},
+]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "win32-setctime"
+version = "1.1.0"
+description = "A small Python utility to set file creation time on Windows"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"},
+ {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"},
+]
+
+[package.extras]
+dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"]
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[[package]]
+name = "yarl"
+version = "1.9.4"
+description = "Yet another URL library"
+optional = false
+python-versions = ">=3.7"
+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"},
+]
+
+[package.dependencies]
+idna = ">=2.0"
+multidict = ">=4.0"
+
+[package.source]
+type = "legacy"
+url = "https://mirrors.aliyun.com/pypi/simple"
+reference = "aliyun"
+
+[metadata]
+lock-version = "2.0"
+python-versions = "^3.10"
+content-hash = "d25708fbabbb279615bf02c5e047e88103f29006155043f92a011b23d59da704"
diff --git a/pyproject.toml b/pyproject.toml
index 8ea182d..b7469c4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,7 +1,7 @@
[project]
-name = "ANGAANGBOT"
-version = "0.2.0"
-description = "AABT"
+name = "ANGANGBOT"
+version = "2.3.5"
+description = "基于NoneBot2的交互bot"
readme = "README.md"
requires-python = ">=3.8, <4.0"
@@ -12,3 +12,34 @@ adapters = [
plugins = []
plugin_dirs = ["src/plugins"]
builtin_plugins = ["echo"]
+
+[tool.poetry]
+name = "angangbot"
+version = "2.3.5"
+description = "基于NoneBot2的交互bot"
+authors = ["angjustinl "]
+license = "AGPL-3.0"
+readme = "README.md"
+
+[[tool.poetry.source]]
+name = "aliyun"
+default = true
+url = "https://mirrors.aliyun.com/pypi/simple/"
+
+[tool.poetry.dependencies]
+python = "^3.10"
+httpx = "^0.26.0"
+nb-cli = "^1.3.0"
+pillow = "^10.2.0"
+nonebot-adapter-onebot = "^2.4.0"
+nonebot-plugin-apscheduler = "^0.4.0"
+nonebot2 = {extras = ["fastapi"], version = "^2.1.3"}
+nonebot-plugin-guild-patch = "^0.2.3"
+nonebot-plugin-PicMenu = "^0.2"
+nonebot-plugin-weather-lite = "^0.0.1"
+nonebot-plugin-pixivbot = "^2.0.3"
+nonebot-plugin-fortune = "^0.4.12"
+
+[build-system]
+requires = ["poetry-core"]
+build-backend = "poetry.core.masonry.api"
diff --git a/src/plugins/nonebot-plugin-random/__init__.py b/src/plugins/nonebot-plugin-random/__init__.py
new file mode 100644
index 0000000..04ef4d4
--- /dev/null
+++ b/src/plugins/nonebot-plugin-random/__init__.py
@@ -0,0 +1,14 @@
+from .matchers import *
+from nonebot.plugin import PluginMetadata
+
+__version__ = "0.0.9"
+__plugin_meta__ = PluginMetadata(
+ name="随机抽图/语音",
+ description="Nonebot2 通用抽图/语音插件",
+ usage="\n".join(COMMANDS),
+ extra={
+ "version": __version__,
+ "license": "MIT",
+ "author": "jcjrobert ",
+ },
+)
\ No newline at end of file
diff --git a/src/plugins/nonebot-plugin-random/depends.py b/src/plugins/nonebot-plugin-random/depends.py
new file mode 100644
index 0000000..8b65693
--- /dev/null
+++ b/src/plugins/nonebot-plugin-random/depends.py
@@ -0,0 +1,24 @@
+from nonebot.rule import Rule
+from nonebot.permission import SUPERUSER, Permission
+from nonebot.adapters.onebot.v11.permission import (
+ GROUP_ADMIN,
+ GROUP_OWNER,
+)
+from nonebot.adapters.onebot.v11 import MessageEvent
+
+def check_tome(is_tome: bool) -> Rule:
+ def checker(event: MessageEvent) -> bool:
+ if not is_tome:
+ return True
+ return event.is_tome()
+
+ return Rule(checker)
+
+def check_modify(modify_admin_only: bool) -> Permission:
+ if modify_admin_only:
+ return GROUP_OWNER | GROUP_ADMIN | SUPERUSER
+
+ def permission() -> bool:
+ return True
+
+ return Permission(permission)
\ No newline at end of file
diff --git a/src/plugins/nonebot-plugin-random/download.py b/src/plugins/nonebot-plugin-random/download.py
new file mode 100644
index 0000000..ea904a7
--- /dev/null
+++ b/src/plugins/nonebot-plugin-random/download.py
@@ -0,0 +1,15 @@
+import httpx
+import asyncio
+from nonebot.log import logger
+
+async def download_url(url: str) -> bytes:
+ async with httpx.AsyncClient() as client:
+ for i in range(3):
+ try:
+ resp = await client.get(url, timeout=20)
+ resp.raise_for_status()
+ return resp.content
+ except Exception as e:
+ logger.warning(f"Error downloading {url}, retry {i}/3: {e}")
+ await asyncio.sleep(3)
+ raise Exception(f"{url} 下载失败!")
\ No newline at end of file
diff --git a/src/plugins/nonebot-plugin-random/matchers.py b/src/plugins/nonebot-plugin-random/matchers.py
new file mode 100644
index 0000000..8d6a3c0
--- /dev/null
+++ b/src/plugins/nonebot-plugin-random/matchers.py
@@ -0,0 +1,307 @@
+import random
+import json
+import shlex
+import imghdr
+import hashlib
+from datetime import datetime
+from pathlib import Path
+import traceback
+
+from nonebot.matcher import Matcher
+from nonebot.typing import T_Handler, T_State
+from nonebot.params import _command_arg
+from nonebot import logger
+from nonebot import on_command, on_keyword, on_regex
+from nonebot.adapters.onebot.v11 import (
+ Bot,
+ Message,
+ MessageSegment,
+ GroupMessageEvent
+)
+
+from .utils import *
+from .depends import *
+from .models import *
+from .download import *
+
+data_path = Path() / "data" / "random"
+COMMANDS = []
+
+async def bot_send(
+ path:Path,
+ type:str,
+ bot:Bot,
+ event:GroupMessageEvent,
+ output_prefix:str,
+ output_suffix:str,
+ is_at_sender:bool,
+):
+ output_prefix = replace_message(output_prefix,path)
+ output_suffix = replace_message(output_suffix,path)
+ if type == "image":
+ await bot.send(
+ event=event,
+ message=Message(output_prefix)+
+ MessageSegment.image(file=f"file:///{path.resolve()}")+
+ Message(output_suffix),
+ at_sender=is_at_sender
+ )
+ elif type == "record":
+ await bot.send(
+ event=event,
+ message=MessageSegment.record(file=f"file:///{path.resolve()}")
+ )
+ elif type == "video":
+ await bot.send(
+ event=event,
+ message=MessageSegment.video(file=f"file:///{path.resolve()}")
+ )
+
+def get_files(
+ dir_name: str,
+ type: str,
+):
+ files = []
+ dirs = [data_path.joinpath(dir_name)]
+ while dirs:
+ for i in dirs[0].iterdir():
+ if is_file(type, i):
+ files.append(i)
+ elif i.is_dir():
+ dirs.append(i)
+ dirs.pop(0)
+ return files
+
+def create_matchers():
+ def handler(
+ dir_name: str,
+ config: RandomDetailConfig,
+ is_specify: bool = False,
+ ) -> T_Handler:
+ async def handle(
+ matcher: Matcher,
+ bot: Bot,
+ event: GroupMessageEvent,
+ state: T_State,
+ ):
+ try:
+ files = get_files(dir_name, config.draw_output)
+ get_file = random.choice(files)
+ if is_specify:
+ arg = str(_command_arg(state))
+ if arg:
+ for file in files:
+ if file.name.startswith(arg):
+ get_file = file
+ break
+ except IndexError:
+ traceback.print_exc()
+ await matcher.finish(message=f"当前文件夹/{dir_name}下没有文件,请放置任意文件并配置好后再使用命令")
+ except:
+ traceback.print_exc()
+ await matcher.finish(message="出现未知错误,请自行查看日志解决")
+ await bot_send(
+ path=get_file,
+ type=config.draw_output,
+ bot=bot,
+ event=event,
+ output_prefix=config.output_prefix,
+ output_suffix=config.output_suffix,
+ is_at_sender=config.is_at_sender,
+ )
+
+ return handle
+
+ def insert_image_handler(
+ dir_name: str,
+ commands: List[str],
+ ) -> T_Handler:
+ async def handle(
+ bot: Bot,
+ event: GroupMessageEvent,
+ ):
+ images: List[bytes] = []
+ images_name: List[str] = []
+
+ success: int = 0
+ fail: int = 0
+
+ if event.reply:
+ for img in event.reply.message["image"]:
+ try:
+ _img = await download_url(str(img.data.get("url", "")))
+ success += 1
+ images.append(_img)
+ except:
+ fail += 1
+
+ msg: Message = event.dict()["message"]
+ for msg_seg in msg:
+ if msg_seg.type == "image":
+ try:
+ _img = await download_url(str(msg_seg.data.get("url", "")))
+ success += 1
+ images.append(_img)
+ except:
+ fail += 1
+ elif msg_seg.type == "text":
+ raw_text = str(msg_seg)
+ for command in commands:
+ raw_text = raw_text.replace(command, "")
+ try:
+ texts = shlex.split(raw_text)
+ except:
+ texts = raw_text.split()
+ images_name += texts
+
+ base = 0
+ while len(images_name) < len(images):
+ images_name.append(str(int(datetime.now().timestamp())+base))
+ base += 1
+ images_name = images_name[:len(images)]
+ images_name = [f"{img_name}.{imghdr.what(None, h=images[i])}" for i,img_name in enumerate(images_name)]
+
+ path = data_path.joinpath(dir_name)
+ for i,img in enumerate(images):
+ img_path = path / images_name[i]
+ with img_path.open("wb+") as f:
+ f.write(img)
+
+ tosend = f"添加完成,成功{success}张,失败{fail}张,可以直接用于抽取"
+ await bot.send(event=event,message=tosend,at_sender=True)
+
+ return handle
+
+ def delete_image_handler(
+ dir_name: str
+ ) -> T_Handler:
+ async def handle(
+ bot: Bot,
+ event: GroupMessageEvent,
+ ):
+ images: List[bytes] = []
+ imgs_hash: List[str] = []
+
+ """
+ 获取图片
+ """
+ if event.reply:
+ for img in event.reply.message["image"]:
+ try:
+ _img = await download_url(str(img.data.get("url", "")))
+ images.append(_img)
+ except:
+ traceback.print_exc()
+ logger.error("删除图片读取失败")
+
+ msg: Message = event.dict()["message"]
+ for msg_seg in msg:
+ if msg_seg.type == "image":
+ try:
+ _img = await download_url(str(msg_seg.data.get("url", "")))
+ images.append(_img)
+ except:
+ traceback.print_exc()
+ logger.error("删除图片读取失败")
+ imgs_hash = [hashlib.md5(image).hexdigest() for image in images]
+
+ files = get_files(dir_name, "image")
+
+ remove_file = 0
+ for f in files:
+ f_hash = hashlib.md5(f.read_bytes()).hexdigest()
+ if f_hash in imgs_hash:
+ f.unlink()
+ remove_file += 1
+
+ await bot.send(event=event,message=f"删除图片成功,一共删除了{remove_file}张图片",at_sender=True)
+
+ return handle
+
+ if not data_path.exists():
+ data_path.mkdir(parents=True, exist_ok=True)
+ for dir in data_path.iterdir():
+ if dir.is_dir():
+ dir_name = dir.name
+ config_path = dir / "config.json"
+ config_dict = {}
+ if config_path.exists():
+ try:
+ with config_path.open("r",encoding="UTF-8") as f:
+ config_dict = json.loads(f.read())
+ except:
+ traceback.print_exc()
+ logger.error(f"/{dir_name}配置文件格式错误,请检查格式并进行重新配置")
+ config = RandomDetailConfig(dir_name=dir_name,config_dict=config_dict)
+ if config.message_type == "command":
+ COMMANDS.append(("@我 + " if config.is_tome else "") + '/'.join(config.message))
+ on_command(
+ config.message[0],
+ aliases=set(config.message[1:]),
+ block=True,
+ priority=12,
+ rule=check_tome(config.is_tome),
+ ).append_handler(
+ handler(
+ dir_name=dir_name,
+ config=config,
+ is_specify=True,
+ )
+ )
+ if config.draw_output == "image":
+ on_command(
+ config.insert_message[0],
+ aliases=set(config.insert_message[1:]),
+ block=True,
+ priority=12,
+ rule=check_tome(config.is_tome),
+ permission=check_modify(config.modify_admin_only),
+ ).append_handler(
+ insert_image_handler(
+ dir_name=dir_name,
+ commands=config.insert_message,
+ )
+ )
+ on_command(
+ config.delete_message[0],
+ aliases=set(config.delete_message[1:]),
+ block=True,
+ priority=12,
+ rule=check_tome(config.is_tome),
+ permission=check_modify(config.modify_admin_only),
+ ).append_handler(
+ delete_image_handler(
+ dir_name=dir_name,
+ )
+ )
+ elif config.message_type == "keyword":
+ COMMANDS.append(f"关键词含有{config.message[0]}{' 并@我' if config.is_tome else ''}")
+ on_keyword(
+ config.message[0],
+ block=True,
+ priority=12,
+ rule=check_tome(config.is_tome),
+ ).append_handler(
+ handler(
+ dir_name=dir_name,
+ config=config,
+ )
+ )
+ elif config.message_type == "regex":
+ if len(config.message) <= 1:
+ logger.error(f"/{dir_name}使用正则匹配时应保证message有两项,第一项是正则表达式,第二项是匹配表达式的命令(用于命令展示)")
+ continue
+ COMMANDS.append(f"{'@我 + ' if config.is_tome else ''}{config.message[1]}")
+ on_regex(
+ config.message[0],
+ block=True,
+ priority=12,
+ rule=check_tome(config.is_tome),
+ ).append_handler(
+ handler(
+ dir_name=dir_name,
+ config=config,
+ )
+ )
+
+create_matchers()
\ No newline at end of file
diff --git a/src/plugins/nonebot-plugin-random/models.py b/src/plugins/nonebot-plugin-random/models.py
new file mode 100644
index 0000000..c028b31
--- /dev/null
+++ b/src/plugins/nonebot-plugin-random/models.py
@@ -0,0 +1,55 @@
+from typing import List
+
+DRAW_OUTPUT_TYPES = ["text", "image", "record", "video"]
+MESSAGE_TYPES = ["command", "keyword", "regex"]
+
+def is_list_str(l):
+ return isinstance(l, list) and sum([isinstance(i, str) for i in l])
+
+class RandomDetailConfig:
+ draw_output: str
+ message_type: str
+ message: List[str]
+ insert_message: List[str]
+ delete_message: List[str]
+ modify_admin_only: bool
+ is_tome: bool
+ output_prefix: str
+ output_suffix: str
+ is_at_sender: bool
+
+ def __init__(self, dir_name: str, config_dict: dict):
+ self.draw_output = config_dict.get("draw_output")
+ if self.draw_output not in DRAW_OUTPUT_TYPES:
+ self.draw_output = "image"
+
+ self.message_type = config_dict.get("message_type")
+ if self.message_type not in MESSAGE_TYPES:
+ self.message_type = "command"
+
+ self.message = config_dict.get("message")
+ if not is_list_str(self.message):
+ self.message = [f"随机{dir_name}"]
+
+ if self.draw_output == "image":
+ self.insert_message = config_dict.get("insert_message")
+ if not is_list_str(self.insert_message):
+ self.insert_message = [f"添加{msg}" for msg in self.message]
+
+ self.delete_message = config_dict.get("delete_message")
+ if not is_list_str(self.delete_message):
+ self.delete_message = [f"删除{msg}" for msg in self.message]
+
+ self.modify_admin_only = bool(config_dict.get("modify_admin_only"))
+
+ self.is_tome = bool(config_dict.get("is_tome"))
+
+ self.output_prefix = config_dict.get("output_prefix")
+ if not isinstance(self.output_prefix, str):
+ self.output_prefix = ""
+
+ self.output_suffix = config_dict.get("output_suffix")
+ if not isinstance(self.output_suffix, str):
+ self.output_suffix = ""
+
+ self.is_at_sender = bool(config_dict.get("is_at_sender"))
\ No newline at end of file
diff --git a/src/plugins/nonebot-plugin-random/utils.py b/src/plugins/nonebot-plugin-random/utils.py
new file mode 100644
index 0000000..6e0b10e
--- /dev/null
+++ b/src/plugins/nonebot-plugin-random/utils.py
@@ -0,0 +1,24 @@
+from pathlib import Path
+
+def is_image_file(path:Path) -> bool:
+ return path.suffix in [".gif",".png",".jpg",".jpeg"]
+
+def is_record_file(path:Path) -> bool:
+ return path.suffix in [".mp3",".wav",".ogg"]
+
+def is_video_file(path:Path) -> bool:
+ return path.suffix in [".mp4",".avi",".flv",".wmv",".mov",".mpg",".mpeg"]
+
+def is_file(type:str,path:Path) -> bool:
+ if type == "image":
+ return is_image_file(path)
+ elif type == "record":
+ return is_record_file(path)
+ elif type == "video":
+ return is_video_file(path)
+ else:
+ return False
+
+def replace_message(msg:str,path:Path) -> str:
+ return msg.replace("{filename}",path.name) \
+ .replace("{filestem}",path.stem)
\ No newline at end of file
diff --git a/src/plugins/nonebot_plugin_HttpCat/__init__.py b/src/plugins/nonebot_plugin_HttpCat/__init__.py
new file mode 100644
index 0000000..cb50ff3
--- /dev/null
+++ b/src/plugins/nonebot_plugin_HttpCat/__init__.py
@@ -0,0 +1,23 @@
+from nonebot import on_command
+from nonebot.adapters.onebot.v11 import MessageSegment,Message
+from nonebot.params import CommandArg
+
+from .httpcat import httpcat_msgs
+
+http_cat = on_command('http_cat',aliases={'httpcat','http猫'}, priority=5, block=True)
+
+@http_cat.handle()
+async def _handle(code: Message = CommandArg()):
+ url = "https://httpcats.com/{}.jpg".format(code)
+ msgs = await httpcat_msgs('http://www.httpstatus.cn/{}'.format(code))
+ await http_cat.finish(msgs+MessageSegment.image(file=url, cache=False), at_sender=True)
+
+#httpx异步 await httpcat_msg(code)
+async def httpcat_msg(code):
+ msgs = await httpcat_msgs('http://www.httpstatus.cn/{}'.format(code))
+ return msgs
+
+#url同步 httpcat_pic(code)
+def httpcat_pic(code):
+ url = "https://httpcats.com/{}.jpg".format(code)
+ return str(url)
\ No newline at end of file
diff --git a/src/plugins/nonebot_plugin_HttpCat/httpcat.py b/src/plugins/nonebot_plugin_HttpCat/httpcat.py
new file mode 100644
index 0000000..93b1eef
--- /dev/null
+++ b/src/plugins/nonebot_plugin_HttpCat/httpcat.py
@@ -0,0 +1,14 @@
+import httpx
+from bs4 import BeautifulSoup
+
+async def httpcat_msgs(url):
+ async with httpx.AsyncClient(verify=False, timeout=None) as client:
+ resp = await client.get(
+ url,
+ )
+ page = resp.text
+ soup = BeautifulSoup(page, 'html.parser')
+ bf = soup.find('p')
+ waste = soup.find('a')
+ bf.replace_with(waste,'')
+ return bf
\ No newline at end of file
diff --git a/src/plugins/nonebot_plugin_animalVoice/AnimalVoice/__init__.py b/src/plugins/nonebot_plugin_animalVoice/AnimalVoice/__init__.py
new file mode 100644
index 0000000..c5ddab6
--- /dev/null
+++ b/src/plugins/nonebot_plugin_animalVoice/AnimalVoice/__init__.py
@@ -0,0 +1,71 @@
+#兽音译者,一种将“呜嗷啊~”四个字符,通过特殊算法,将明文进行重新组合的加密算法。一种新的咆哮体加密算法。还可以将四个字符任意换成其它的字符,进行加密。
+
+class HowlingAnimalsTranslator:
+
+ __animalVoice="嗷呜啊~"
+
+ def __init__(self,newAnimalVoice=None):
+ self.setAnimalVoice(newAnimalVoice)
+
+ def convert(self,txt=""):
+ txt=txt.strip()
+ if(txt.__len__()<1):
+ return ""
+ result=self.__animalVoice[3]+self.__animalVoice[1]+self.__animalVoice[0]
+ offset=0
+ for t in txt:
+ c=ord(t)
+ b=12
+ while(b>=0):
+ hex=(c>>b)+offset&15
+ offset+=1
+ result+=self.__animalVoice[int(hex>>2)]
+ result+=self.__animalVoice[int(hex&3)]
+ b-=4
+ result+=self.__animalVoice[2]
+ return result
+
+ def deConvert(self,txt):
+ txt=txt.strip()
+ if(not self.identify(txt)):
+ return "Incorrect format!"
+ result=""
+ i=3
+ offset=0
+ while(i11):
+ if(txt[0]==self.__animalVoice[3] and txt[1]==self.__animalVoice[1] and txt[2]==self.__animalVoice[0] and txt[-1]==self.__animalVoice[2] and ((txt.__len__()-4)%8)==0):
+ for t in txt:
+ if(not self.__animalVoice.__contains__(t)):
+ return False
+ return True
+ return False
+
+ def setAnimalVoice(self,voiceTxt):
+ if(voiceTxt):
+ voiceTxt=voiceTxt.strip()
+ if(voiceTxt.__len__()==4):
+ self.__animalVoice=voiceTxt
+ return True
+ return False
+
+ def getAnimalVoice(self):
+ return self.__animalVoice
\ No newline at end of file
diff --git a/src/plugins/nonebot_plugin_animalVoice/AnimalVoice/converter.py b/src/plugins/nonebot_plugin_animalVoice/AnimalVoice/converter.py
new file mode 100644
index 0000000..d6453d6
--- /dev/null
+++ b/src/plugins/nonebot_plugin_animalVoice/AnimalVoice/converter.py
@@ -0,0 +1,14 @@
+from . import HowlingAnimalsTranslator
+
+#实例化
+animalVoice = HowlingAnimalsTranslator()
+
+#编译
+def msg_convert(input):
+ msg = animalVoice.convert(input)
+ return msg
+
+#反编译
+def msg_deconvert(input):
+ msg = animalVoice.deConvert(input)
+ return msg
\ No newline at end of file
diff --git a/src/plugins/nonebot_plugin_animalVoice/Cheru/__init__.py b/src/plugins/nonebot_plugin_animalVoice/Cheru/__init__.py
new file mode 100644
index 0000000..0646d6a
--- /dev/null
+++ b/src/plugins/nonebot_plugin_animalVoice/Cheru/__init__.py
@@ -0,0 +1,46 @@
+import re
+from itertools import zip_longest
+
+CHERU_SET = '切卟叮咧哔唎啪啰啵嘭噜噼巴拉蹦铃'
+CHERU_DIC = {c: i for i, c in enumerate(CHERU_SET)}
+ENCODING = 'gb18030'
+rex_split = re.compile(r'\b', re.U)
+rex_word = re.compile(r'^\w+$', re.U)
+rex_cheru_word: re.Pattern = re.compile(rf'切[{CHERU_SET}]+', re.U)
+
+
+def grouper(iterable, n, fillvalue=None):
+ args = [iter(iterable)] * n
+ return zip_longest(*args, fillvalue=fillvalue)
+
+
+def word2cheru(w: str) -> str:
+ c = ['切']
+ for b in w.encode(ENCODING):
+ c.append(CHERU_SET[b & 0xf])
+ c.append(CHERU_SET[(b >> 4) & 0xf])
+ return ''.join(c)
+
+
+def cheru2word(c: str) -> str:
+ if not c[0] == '切' or len(c) < 2:
+ return c
+ b = []
+ for b1, b2 in grouper(c[1:], 2, '切'):
+ x = CHERU_DIC.get(b2, 0)
+ x = x << 4 | CHERU_DIC.get(b1, 0)
+ b.append(x)
+ return bytes(b).decode(ENCODING, 'replace')
+
+
+def str2cheru(s: str) -> str:
+ c = []
+ for w in rex_split.split(s):
+ if rex_word.search(w):
+ w = word2cheru(w)
+ c.append(w)
+ return ''.join(c)
+
+
+def cheru2str(c: str) -> str:
+ return rex_cheru_word.sub(lambda w: cheru2word(w.group()), c)
\ No newline at end of file
diff --git a/src/plugins/nonebot_plugin_animalVoice/LICENSE b/src/plugins/nonebot_plugin_animalVoice/LICENSE
new file mode 100644
index 0000000..f288702
--- /dev/null
+++ b/src/plugins/nonebot_plugin_animalVoice/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/src/plugins/nonebot_plugin_animalVoice/README.md b/src/plugins/nonebot_plugin_animalVoice/README.md
new file mode 100644
index 0000000..23533a7
--- /dev/null
+++ b/src/plugins/nonebot_plugin_animalVoice/README.md
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+# nonebot_plugin_animalVoice
+
+_✨Nonebot兽语译者插件✨_
+
+---
+
+
+
+
+
+
+
+
+
+
+
+---
+
+
+## ✔ 使用例
+
+![3`$HP~HVN%SK(IV@2HO7X{M](https://user-images.githubusercontent.com/96008766/210118707-b00e90ff-ce8c-4fdb-bcd9-f3a18c2ebc50.png)
+
+![OYJ5N2~Z@XZ)B6FL %MEIKA](https://user-images.githubusercontent.com/96008766/210118729-8e8a6ff0-f911-4514-aac9-a87f714051e9.png)
+
+## 💿 安装
+
+### 1. nb-cli安装(推荐)
+bot根目录下打开命令行,执行nb命令安装插件,插件配置会自动添加至配置文件
+
+```
+nb plugin install nonebot_plugin_animalVoice
+```
+
+### 2. pip安装
+
+```
+pip install nonebot_plugin_animalVoice --upgrade
+
+```
+
+打开 nonebot2 项目的 ```bot.py``` 文件, 在其中写入
+```nonebot.load_plugin('nonebot_plugin_animalVoice')```
+
+或在bot路径```pyproject.toml```的```[tool.nonebot]```的```plugins```中添加```nonebot_plugin_animalVoice```即可
+pyproject.toml配置例如:
+
+```
+
+[tool.nonebot]
+plugin_dirs = ["src/plugins"]
+plugins = ["nonebot_plugin_animalVoice","xxxxx"]
+
+```
+
+
+## 🎉 使用
+### 指令表
+| 指令 | 需要@ | 范围 | 说明 |
+|:-----:|:----:|:----:|:----:|
+| [兽音加密]/[convert] | 否 | 群聊/私聊 | 发送需要加密的文字 |
+| [兽音解密]/[deconvert] | 否 | 群聊/私聊 | 发送需要解密的文字 |
+| [切噜一下]/[cherulize] | 否 | 群聊/私聊 | 发送需要解密的文字 |
+| [切噜~]/[decherulize] | 否 | 群聊/私聊 | 发送需要解密的文字 |
+
+
+**注意**
+
+默认情况下, 您应该在指令前加上命令前缀, 通常是 /
+
+
+### 🧡特别感谢
+
+HoshinoBot: https://github.com/Ice-Cirno/HoshinoBot 提供了切噜切噜的算法
diff --git a/src/plugins/nonebot_plugin_animalVoice/__init__.py b/src/plugins/nonebot_plugin_animalVoice/__init__.py
new file mode 100644
index 0000000..6ca5a4e
--- /dev/null
+++ b/src/plugins/nonebot_plugin_animalVoice/__init__.py
@@ -0,0 +1,8 @@
+import nonebot
+from pathlib import Path
+from . import animalvoice_main,cheru_main
+
+_sub_plugins = set()
+_sub_plugins |= nonebot.load_plugins(
+ str((Path(__file__).parent / "plugins").
+ resolve()))
\ No newline at end of file
diff --git a/src/plugins/nonebot_plugin_animalVoice/animalvoice_main.py b/src/plugins/nonebot_plugin_animalVoice/animalvoice_main.py
new file mode 100644
index 0000000..ac68888
--- /dev/null
+++ b/src/plugins/nonebot_plugin_animalVoice/animalvoice_main.py
@@ -0,0 +1,76 @@
+from nonebot import on_command
+from nonebot.params import Arg
+from nonebot.adapters.onebot.v11 import MessageEvent, Message, Bot
+from nonebot.typing import T_State
+
+from .AnimalVoice.converter import msg_convert,msg_deconvert
+
+convert = on_command('兽音加密',aliases={'animalvoice','convert'}, priority=5, block=True)
+deconvert = on_command('兽音解密',aliases={'deanimalvoice','deconvert'}, priority=5, block=True)
+
+@convert.handle()
+async def _(state: T_State):
+ return
+#这里用got是因为必须单独消息发送否则容易乱
+@convert.got("msg", prompt="请发送加密前文字")
+async def get_image(state: T_State,msgs: Message = Arg()):
+ msg_input = msgs
+ if not str:
+ await convert.send("不是文字啊")
+ msg_input = str(msg_input)
+ state["msg"] = msg_input
+
+@convert.handle()
+async def _(bot:Bot,state: T_State,event:MessageEvent):
+ msg_input = str(state["msg"][0])
+ try:
+ msg = msg_convert(msg_input)
+ except Exception as e:
+ await convert.finish("寄,加密失败了,报错为{}".format(e), reply_message=True)
+
+ msgs = []
+ msgs.append({
+ "type": "node",
+ "data": {
+ "name": "昂昂兽音译者bot",
+ "uin": bot.self_id,
+ "content": "加密结果\n{}".format(msg)
+ }
+ }
+ )
+ await bot.call_api('send_group_forward_msg', group_id=event.group_id, messages=msgs)
+ await convert.finish()
+
+
+@deconvert.handle()
+async def _(state: T_State):
+ return
+#这里用got是因为必须单独消息发送否则容易乱
+@deconvert.got("msg", prompt="请发送需要解密的文字")
+async def get_image(state: T_State,msgs: Message = Arg()):
+ msg_input = msgs
+ if not str:
+ await deconvert.send("不是文字啊")
+ msg_input = str(msg_input)
+ state["msg"] = msg_input
+
+@deconvert.handle()
+async def _(bot:Bot,state: T_State,event:MessageEvent):
+ msg_input = str(state["msg"][0])
+ try:
+ msg = msg_deconvert(msg_input)
+ except Exception as e:
+ await deconvert.finish("寄,解密失败了,报错为{}".format(e), reply_message=True)
+
+ msgs = []
+ msgs.append({
+ "type": "node",
+ "data": {
+ "name": "昂昂兽音译者bot",
+ "uin": bot.self_id,
+ "content": "解密结果\n{}".format(msg)
+ }
+ }
+ )
+ await bot.call_api('send_group_forward_msg', group_id=event.group_id, messages=msgs)
+ await deconvert.finish()
\ No newline at end of file
diff --git a/src/plugins/nonebot_plugin_animalVoice/cheru_main.py b/src/plugins/nonebot_plugin_animalVoice/cheru_main.py
new file mode 100644
index 0000000..85dac19
--- /dev/null
+++ b/src/plugins/nonebot_plugin_animalVoice/cheru_main.py
@@ -0,0 +1,77 @@
+from nonebot import on_command
+from nonebot.params import Arg
+from nonebot.adapters.onebot.v11 import MessageEvent, Message, Bot
+from nonebot.typing import T_State
+
+from .Cheru import cheru2str,str2cheru
+
+cherulizing = on_command('切噜一下',aliases={'cherulize'}, priority=5, block=True)
+decherulizing = on_command('切噜~',aliases={'decherulize'}, priority=5, block=True)
+
+
+@cherulizing.handle()
+async def _():
+ return
+#这里用got是因为必须单独消息发送否则容易乱
+@cherulizing.got("msg", prompt="切噜什么切噜~♪")
+async def get_image(bot:Bot,state: T_State,msgs: Message = Arg()):
+ msg_input = msgs
+ if len(msg_input) > 500:
+ await bot.send('切、切噜太长切不动勒切噜噜...', at_sender=True)
+ return
+ state["msg"] = msg_input
+
+@cherulizing.handle()
+async def _(bot:Bot,state: T_State,event:MessageEvent):
+ msg_input = str(state["msg"][0])
+ try:
+ msg = str2cheru(msg_input)
+ except Exception as e:
+ await cherulizing.finish("切、切噜报错切不动勒切噜噜{}".format(e), reply_message=True)
+
+ msgs = []
+ msgs.append({
+ "type": "node",
+ "data": {
+ "name": "昂昂切噜bot",
+ "uin": bot.self_id,
+ "content": '切噜~♪\n{}'.format(msg)
+ }
+ }
+ )
+ await bot.call_api('send_group_forward_msg', group_id=event.group_id, messages=msgs)
+ await cherulizing.finish()
+
+
+@decherulizing.handle()
+async def _(state: T_State):
+ return
+#这里用got是因为必须单独消息发送否则容易乱
+@decherulizing.got("msg", prompt="请发送需要解密的文字")
+async def get_image(bot:Bot,state: T_State,msgs: Message = Arg()):
+ msg_input = msgs
+ if len(msg_input) > 1501:
+ await bot.send('切、切噜太长切不动勒切噜噜...', at_sender=True)
+ return
+ state["msg"] = msg_input
+
+@decherulizing.handle()
+async def _(bot:Bot,state: T_State,event:MessageEvent):
+ msg_input = str(state["msg"][0])
+ try:
+ msg = '你的的切噜噜是:\n{}'.format(cheru2str(msg_input))
+ except Exception as e:
+ await decherulizing.finish("切、切噜报错切不动勒切噜噜{}".format(e), reply_message=True)
+
+ msgs = []
+ msgs.append({
+ "type": "node",
+ "data": {
+ "name": "昂昂切噜bot",
+ "uin": bot.self_id,
+ "content": msg
+ }
+ }
+ )
+ await bot.call_api('send_group_forward_msg', group_id=event.group_id, messages=msgs)
+ await decherulizing.finish()
\ No newline at end of file
diff --git a/src/plugins/nonebot_plugin_animalVoice/converter.py b/src/plugins/nonebot_plugin_animalVoice/converter.py
new file mode 100644
index 0000000..936d63a
--- /dev/null
+++ b/src/plugins/nonebot_plugin_animalVoice/converter.py
@@ -0,0 +1,14 @@
+from .AnimalVoice import HowlingAnimalsTranslator
+
+#实例化
+animalVoice = HowlingAnimalsTranslator()
+
+#编译
+def msg_convert(input):
+ msg = animalVoice.convert(input)
+ return msg
+
+#反编译
+def msg_deconvert(input):
+ msg = animalVoice.deConvert(input)
+ return msg
\ No newline at end of file
diff --git a/src/plugins/nonebot_plugin_animalVoice/main.py b/src/plugins/nonebot_plugin_animalVoice/main.py
new file mode 100644
index 0000000..4a54d85
--- /dev/null
+++ b/src/plugins/nonebot_plugin_animalVoice/main.py
@@ -0,0 +1,76 @@
+from nonebot import on_command
+from nonebot.params import CommandArg,Arg
+from nonebot.adapters.onebot.v11 import MessageEvent, Message, Bot
+from nonebot.typing import T_State
+
+from .converter import msg_convert,msg_deconvert
+
+convert = on_command('兽音加密',aliases={'animalvoice','convert'}, priority=5, block=True)
+deconvert = on_command('兽音解密',aliases={'deanimalvoice','deconvert'}, priority=5, block=True)
+
+@convert.handle()
+async def _(state: T_State):
+ return
+#这里用got是因为必须单独消息发送否则容易乱
+@convert.got("msg", prompt="请发送加密前文字")
+async def get_image(state: T_State,msgs: Message = Arg()):
+ msg_input = msgs
+ if not str:
+ await convert.send("不是文字啊")
+ msg_input = str(msg_input)
+ state["msg"] = msg_input
+
+@convert.handle()
+async def _(bot:Bot,state: T_State,event:MessageEvent):
+ msg_input = str(state["msg"][0])
+ try:
+ msg = msg_convert(msg_input)
+ except Exception as e:
+ await convert.finish("寄,加密失败了,报错为{}".format(e), reply_message=True)
+
+ msgs = []
+ msgs.append({
+ "type": "node",
+ "data": {
+ "name": "昂昂兽音译者bot",
+ "uin": bot.self_id,
+ "content": "加密结果\n{}".format(msg)
+ }
+ }
+ )
+ await bot.call_api('send_group_forward_msg', group_id=event.group_id, messages=msgs)
+ await convert.finish()
+
+
+@deconvert.handle()
+async def _(state: T_State):
+ return
+#这里用got是因为必须单独消息发送否则容易乱
+@deconvert.got("msg", prompt="请发送需要解密的文字")
+async def get_image(state: T_State,msgs: Message = Arg()):
+ msg_input = msgs
+ if not str:
+ await deconvert.send("不是文字啊")
+ msg_input = str(msg_input)
+ state["msg"] = msg_input
+
+@deconvert.handle()
+async def _(bot:Bot,state: T_State,event:MessageEvent):
+ msg_input = str(state["msg"][0])
+ try:
+ msg = msg_deconvert(msg_input)
+ except Exception as e:
+ await deconvert.finish("寄,解密失败了,报错为{}".format(e), reply_message=True)
+
+ msgs = []
+ msgs.append({
+ "type": "node",
+ "data": {
+ "name": "昂昂兽音译者bot",
+ "uin": bot.self_id,
+ "content": "解密结果\n{}".format(msg)
+ }
+ }
+ )
+ await bot.call_api('send_group_forward_msg', group_id=event.group_id, messages=msgs)
+ await convert.finish()
\ No newline at end of file
diff --git a/src/plugins/nonebot_plugin_eventdone/.gitignore b/src/plugins/nonebot_plugin_eventdone/.gitignore
new file mode 100644
index 0000000..b6e4761
--- /dev/null
+++ b/src/plugins/nonebot_plugin_eventdone/.gitignore
@@ -0,0 +1,129 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+pip-wheel-metadata/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+.python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
diff --git a/src/plugins/nonebot_plugin_eventdone/LICENSE b/src/plugins/nonebot_plugin_eventdone/LICENSE
new file mode 100644
index 0000000..1dc1832
--- /dev/null
+++ b/src/plugins/nonebot_plugin_eventdone/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 PadorFelice
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/src/plugins/nonebot_plugin_eventdone/README.md b/src/plugins/nonebot_plugin_eventdone/README.md
new file mode 100644
index 0000000..afe2161
--- /dev/null
+++ b/src/plugins/nonebot_plugin_eventdone/README.md
@@ -0,0 +1,15 @@
+# Nonebot_plugin_eventdone
+远程好友申请事件的处理~这是我第一次写插件喵~请多多指教,有问题请尽快联系我喵~
+
+
+使用说明
+1.直接下载压缩包/使用git clone gh repo clone PadorFelice/Nonebot_plugin_eventdone
+2.解压放入你的plugin文件夹即可食用喵~(记得查看PS!!!)
+
+PS:罐头是我家猫猫的名字,您当然也可以改成您喜欢的东西的名字
+ 在运行前请先检查import的组件您是否已经准备齐全,超级用户是否在.env中设置完毕
+ 本组件基于nonebot运行,如果您使用的不是nonebot,出错概不负责
+
+有疑问(请事先查看提问的智慧)
+ 自己想
+ issue
diff --git a/src/plugins/nonebot_plugin_eventdone/__init__.py b/src/plugins/nonebot_plugin_eventdone/__init__.py
new file mode 100644
index 0000000..f15c974
--- /dev/null
+++ b/src/plugins/nonebot_plugin_eventdone/__init__.py
@@ -0,0 +1,80 @@
+# modified from https://github.com/PadorFelice/Nonebot_plugin_eventdone
+import time
+import json
+import aiofiles
+from nonebot import get_driver
+from nonebot.adapters.onebot.v11 import Bot, FriendRequestEvent, PrivateMessageEvent
+from nonebot.permission import SUPERUSER
+from nonebot.plugin import on_command, on_request
+from .config import Config
+
+# 配置项
+config = Config.parse_obj(get_driver().config.dict())
+conf_path = config.conf_path
+
+# 获取超级用户的id
+super_id = get_driver().config.superusers
+
+
+async def friend_request_rule(event: FriendRequestEvent):
+ async with aiofiles.open(conf_path, "r", encoding="utf-8") as f:
+ obj = json.loads(await f.read())
+ add_qq = int(json.loads(event.json())["user_id"])
+ qq_set = set(obj["add_qq_req_list"]["qq"])
+ return add_qq not in qq_set
+
+
+
+# 超级用户推送添加机器人好友请求事件
+add_friend = on_request(friend_request_rule, priority=1, block=True)
+
+
+@add_friend.handle()
+async def _(bot: Bot, event: FriendRequestEvent):
+ try:
+ async with aiofiles.open(conf_path, "r", encoding="utf-8") as f:
+ obj = json.loads(await f.read())
+ qq_list = list(obj["add_qq_req_list"]["qq"])
+ add_req = json.loads(event.json())
+ add_qq = add_req["user_id"]
+ qq_list.append(add_qq)
+ comment = add_req["comment"]
+ flag = add_req["flag"]
+ realtime = time.strftime("%Y年%m月%d日 %H:%M:%S", time.localtime(add_req["time"]))
+ obj["add_qq_req_list"]["qq"] = qq_list
+ obj["add_qq_req_list"]["flag"] = flag
+ async with aiofiles.open(conf_path, "w", encoding="utf-8") as f:
+ await f.write(json.dumps(obj, indent=4))
+ for su_qq in super_id:
+ await bot.send_private_msg(user_id=int(su_qq),
+ message=f"QQ:{add_qq} 请求添加AABT为好友!\n请求添加时间:{realtime}\n验证信息为:{comment}")
+ except Exception as e:
+ for su_qq in super_id:
+ await bot.send_private_msg(user_id=int(su_qq), message=f"AABT坏掉了\n错误信息:{e}")
+
+
+# 超级用户使用,同意好友添加机器人请求
+agree_qq_add = on_command("同意", permission=SUPERUSER)
+
+
+@agree_qq_add.handle()
+async def _(bot: Bot, event: PrivateMessageEvent):
+ try:
+ async with aiofiles.open(conf_path, "r", encoding="utf-8") as f:
+ obj = json.loads(await f.read())
+ qq_set = set(obj["add_qq_req_list"]["qq"])
+ flag = obj["add_qq_req_list"]["flag"]
+ user_id = int(event.get_user_id())
+ agree_id = int(str(event.get_message()).split("同意")[-1]) #在QQ上同意时请加上申请人QQ号
+ if agree_id in qq_set:
+ await bot.send_private_msg(user_id=user_id, message=f"AABT成功添加QQ:{agree_id}为好友!")
+ await bot.set_friend_add_request(flag=flag, approve=True, remark="")
+ obj["add_qq_req_list"]["qq"] = list(qq_set)
+ obj["add_qq_req_list"]["flag"] = ""
+ async with aiofiles.open(conf_path, "w", encoding="utf-8") as f:
+ await f.write(json.dumps(obj, indent=4))
+ else:
+ await bot.send_private_msg(user_id=user_id, message=f"QQ:{agree_id}不在好友申请列表!")
+ except Exception as e:
+ for su_qq in super_id:
+ await bot.send_private_msg(user_id=int(su_qq), message=f"AABT出错了\n错误信息:{e}")
\ No newline at end of file
diff --git a/src/plugins/nonebot_plugin_eventdone/config.py b/src/plugins/nonebot_plugin_eventdone/config.py
new file mode 100644
index 0000000..889f814
--- /dev/null
+++ b/src/plugins/nonebot_plugin_eventdone/config.py
@@ -0,0 +1,6 @@
+from pathlib import Path
+from pydantic import BaseModel, Extra
+
+
+class Config(BaseModel, extra=Extra.ignore):
+ conf_path: str = str(Path(__file__).parent / "set.json")
\ No newline at end of file
diff --git a/src/plugins/nonebot_plugin_setu4/LICENSE b/src/plugins/nonebot_plugin_setu4/LICENSE
new file mode 100644
index 0000000..e6dad8f
--- /dev/null
+++ b/src/plugins/nonebot_plugin_setu4/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Special-Week
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/src/plugins/nonebot_plugin_setu4/__init__.py b/src/plugins/nonebot_plugin_setu4/__init__.py
new file mode 100644
index 0000000..79b24e3
--- /dev/null
+++ b/src/plugins/nonebot_plugin_setu4/__init__.py
@@ -0,0 +1,141 @@
+#https://github.com/Special-Week/nonebot_plugin_setu4
+import contextlib
+from re import I
+
+from nonebot import on_command, on_regex
+from nonebot.adapters.onebot.v11 import GROUP, PRIVATE_FRIEND
+from nonebot.permission import SUPERUSER
+
+from .mamager_handle import manager_handle
+from .send_setu import send_setu
+
+with contextlib.suppress(Exception):
+ from nonebot.plugin import PluginMetadata
+
+ __plugin_meta__ = PluginMetadata(
+ name="setu4",
+ description="内置数据库的setu插件, 尝试降低因为风控发不出图的概率",
+ usage=r"^(setu|色图|涩图|想色色|来份色色|来份色图|想涩涩|多来点|来点色图|来张setu|来张色图|来点色色|色色|涩涩)\s?([x|✖️|×|X|*]?\d+[张|个|份]?)?\s?(r18)?\s?(.*)?",
+ type="application",
+ homepage="https://github.com/Special-Week/nonebot_plugin_setu4",
+ supported_adapters={"~onebot.v11"},
+ extra={
+ "author": "Special-Week",
+ "version": "0.13.114514",
+ "priority": 10,
+ },
+ )
+
+
+# 命令正则表达式
+setu_regex: str = r"^(setu|色图|涩图|想色色|来份色色|来份色图|想涩涩|多来点|来点色图|来张setu|来张色图|来点色色|色色|涩涩)\s?([x|✖️|×|X|*]?\d+[张|个|份]?)?\s?(r18)?\s?(.*)?"
+on_regex(
+ setu_regex,
+ flags=I,
+ permission=PRIVATE_FRIEND | GROUP,
+ priority=20,
+ block=True,
+ handlers=[send_setu.setu_handle],
+)
+
+
+# ----- 白名单添加与解除 -----
+on_command(
+ "setu_wl",
+ block=True,
+ priority=10,
+ permission=SUPERUSER,
+ handlers=[manager_handle.open_setu],
+)
+
+
+# ----- r18添加与解除 -----
+on_command(
+ "setu_r18",
+ block=True,
+ priority=10,
+ permission=SUPERUSER,
+ handlers=[manager_handle.set_r18],
+)
+
+
+# ----- cd时间更新 -----
+on_command(
+ "setu_cd",
+ block=True,
+ priority=10,
+ permission=SUPERUSER,
+ handlers=[manager_handle.set_cd],
+)
+
+
+# ----- 撤回时间更新 -----
+on_command(
+ "setu_wd",
+ block=True,
+ priority=10,
+ permission=SUPERUSER,
+ handlers=[manager_handle.set_wd],
+)
+
+
+# ----- 最大张数更新 -----
+on_command(
+ "setu_mn",
+ block=True,
+ priority=10,
+ permission=SUPERUSER,
+ handlers=[manager_handle.set_maxnum],
+)
+
+
+# ----- 黑名单添加与解除 -----
+on_command(
+ "setu_ban",
+ block=True,
+ priority=10,
+ permission=SUPERUSER,
+ handlers=[manager_handle.ban_setu],
+)
+
+
+# --------------- 发送帮助信息 ---------------
+on_command(
+ "setu_help",
+ block=True,
+ priority=10,
+ aliases={"setu_帮助", "色图_help", "色图_帮助"},
+ handlers=[manager_handle.setu_help],
+)
+
+
+# --------------- 更换代理 ---------------
+on_command(
+ "更换代理",
+ block=True,
+ priority=10,
+ permission=SUPERUSER,
+ aliases={"替换代理", "setu_proxy"},
+ handlers=[manager_handle.replace_proxy, manager_handle.replace_proxy_got],
+)
+
+
+# --------------- 查询黑白名单 ---------------
+on_command(
+ "setu_roster",
+ block=True,
+ priority=10,
+ aliases={"色图名单"},
+ permission=SUPERUSER,
+ handlers=[manager_handle.query_black_white_list],
+)
+
+
+# --------------- 数据库更新 ---------------
+on_command(
+ "setu_db",
+ block=True,
+ priority=10,
+ permission=SUPERUSER,
+ handlers=[manager_handle.setu_db],
+)
diff --git a/src/plugins/nonebot_plugin_setu4/config.py b/src/plugins/nonebot_plugin_setu4/config.py
new file mode 100644
index 0000000..f1f0d61
--- /dev/null
+++ b/src/plugins/nonebot_plugin_setu4/config.py
@@ -0,0 +1,72 @@
+from pathlib import Path
+from typing import List, Union
+
+from loguru import logger
+from nonebot import get_driver
+from pydantic import BaseSettings
+
+DATA_PATH = Path("data/setu4")
+if not DATA_PATH.exists() or not DATA_PATH.is_dir():
+ logger.warning(f"数据目录 {DATA_PATH} 不存在, 将自动创建")
+ DATA_PATH.mkdir(0o755, parents=True, exist_ok=True)
+
+
+class Config(BaseSettings):
+ setu_disable_wlist: bool = False # 是否禁用白名单检查
+ setu_enable_private: bool = False # 是否允许未在白名单的私聊会话使用
+ setu_save: Union[
+ bool, str
+ ] = False # 保存图片的路径, 默认False, 填.env时候希望收到的是字符串而不是True
+ # 数据库路径, 默认使用github的地址
+ database_path: str = "https://raw.githubusercontent.com/Special-Week/nonebot_plugin_setu4/main/nonebot_plugin_setu4/resource/lolicon.db"
+
+ setu_cd: int = 30 # 冷却时间
+ setu_withdraw_time: int = 100 # 撤回时间
+ setu_max_num: int = 10 # 最大数量
+ group_forward_msg: bool = False # 是否合并转发
+
+ setu_nsfw_path: Union[bool, str] = False
+ setu_sfw_path: Union[bool, str] = False
+ scientific_agency: Union[None, str] = None # 科学上网代理地址
+ setu_quality: List[int] = [5, 75]
+ sfw_withdraw: bool = True
+
+ class Config:
+ extra = "ignore"
+
+
+# 实例化配置对象
+config = Config.parse_obj(get_driver().config)
+
+
+# 规范取值范围
+config.setu_cd = max(0, config.setu_cd) # setu_cd不能小于0
+config.setu_withdraw_time = max(
+ 0, config.setu_withdraw_time
+) # 撤回时间不能小于0, 大于100
+config.setu_withdraw_time = min(100, config.setu_withdraw_time)
+config.setu_max_num = max(1, config.setu_max_num) # setu_max_num不能大于1小于25
+config.setu_max_num = min(25, config.setu_max_num)
+
+
+config.setu_nsfw_path = (
+ f"{config.setu_save}/nsfw" if isinstance(config.setu_save, str) else False
+) # nsfw保存路径
+config.setu_sfw_path = (
+ f"{config.setu_save}/sfw" if isinstance(config.setu_save, str) else False
+) # sfw保存路径
+
+
+try:
+ if isinstance(config.setu_nsfw_path, str):
+ Path(config.setu_nsfw_path).mkdir(0o755, parents=True, exist_ok=True)
+ if isinstance(config.setu_sfw_path, str):
+ Path(config.setu_sfw_path).mkdir(0o755, parents=True, exist_ok=True)
+except Exception as e:
+ logger.error(f"创建文件夹失败: {repr(e)}")
+ config.setu_nsfw_path = False
+ config.setu_sfw_path = False
+ config.setu_save = False
+
+
+print(config)
diff --git a/src/plugins/nonebot_plugin_setu4/fetch_resources.py b/src/plugins/nonebot_plugin_setu4/fetch_resources.py
new file mode 100644
index 0000000..71b026b
--- /dev/null
+++ b/src/plugins/nonebot_plugin_setu4/fetch_resources.py
@@ -0,0 +1,47 @@
+from pathlib import Path
+from typing import Union
+
+from httpx import AsyncClient
+from nonebot.log import logger
+
+from .config import config
+
+
+async def download_database() -> str:
+ """
+ 下载更新数据库
+ """
+
+ headers = {
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) "
+ "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
+ }
+ async with AsyncClient(proxies=config.scientific_agency) as client:
+ re = await client.get(url=config.database_path, headers=headers, timeout=120)
+ if re.status_code == 200:
+ with open(Path(__file__).parent / "resource/lolicon.db", "wb") as f:
+ f.write(re.content)
+ logger.success("成功获取lolicon.db")
+ return "成功获取lolicon.db"
+ else:
+ logger.error(f"获取 lolicon.db 失败: {re.status_code}")
+ return f"获取 lolicon.db 失败: {re.status_code}"
+
+
+async def download_pic(url: str, client: AsyncClient) -> Union[bytes, int]:
+ """
+ 下载图片并且返回content(bytes),或者status_code
+
+ params: url: 下载图片的地址
+ """
+
+ try:
+ re = await client.get(
+ url=url, timeout=120, headers={"Referer": "https://www.pixiv.net/"}
+ )
+ if re.status_code != 200:
+ return re.status_code
+ logger.success("成功获取图片")
+ return re.content
+ except Exception:
+ return 408
diff --git a/src/plugins/nonebot_plugin_setu4/get_data.py b/src/plugins/nonebot_plugin_setu4/get_data.py
new file mode 100644
index 0000000..74f84a8
--- /dev/null
+++ b/src/plugins/nonebot_plugin_setu4/get_data.py
@@ -0,0 +1,192 @@
+import asyncio
+import os
+import random
+import sqlite3
+from io import BytesIO
+from pathlib import Path
+from typing import Dict, List, Union
+
+from httpx import AsyncClient
+from loguru import logger
+from PIL import Image
+
+from .config import config
+from .fetch_resources import download_pic
+from .permission_manager import pm
+
+
+class GetData:
+ def __init__(self) -> None:
+ """
+ 初始化保存图片的路径以及该路径下的所有文件名
+ """
+
+ self.all_file_name: Dict[str, set] = {"nsfw": set(), "sfw": set()}
+ if config.setu_save:
+ self.all_file_name["nsfw"] = set(os.listdir(config.setu_nsfw_path))
+ self.all_file_name["sfw"] = set(os.listdir(config.setu_sfw_path))
+ self.database_path: Path = Path(__file__).parent / "resource/lolicon.db"
+
+ @staticmethod
+ async def change_pixel(image, quality: int) -> bytes:
+ """
+ 图像镜像左右翻转, 并且随机修改左上角一个像素点
+ """
+
+ image = image.transpose(Image.FLIP_LEFT_RIGHT)
+ image = image.convert("RGB")
+ image.load()[0, 0] = (
+ random.randint(0, 255),
+ random.randint(0, 255),
+ random.randint(0, 255),
+ )
+ byte_data = BytesIO()
+ image.save(byte_data, format="JPEG", quality=quality)
+ return byte_data.getvalue()
+
+ async def update_status_unavailable(self, urls: str) -> None:
+ """
+ 更新数据库中的图片状态为unavailable
+
+ params: urls: 图片的url
+ """
+
+ conn = sqlite3.connect(self.database_path)
+ cur = conn.cursor()
+ sql = f"UPDATE main set status='unavailable' where urls='{urls}'" # 手搓sql语句
+ cur.execute(sql)
+ conn.commit()
+ conn.close()
+
+ async def get_setu(
+ self,
+ keywords: List[str],
+ num: int = 1,
+ r18: bool = False,
+ quality: int = 75,
+ ) -> List[list]:
+ """
+ 返回列表,内容为setu消息(列表套娃)
+ [
+ [图片(bytes), data(图片信息), True(是否拿到了图), setu_url],
+ [Error(错误), message(错误信息), False(是否拿到了图), setu_url]
+ ]
+
+ params: keywords: 关键词列表
+ num: 数量
+ r18: 是否r18
+ quality: 图片质量
+ """
+
+ data = []
+ conn = sqlite3.connect(self.database_path) # 连接数据库
+ cur = conn.cursor()
+ # sql操作,根据keyword和r18进行查询拿到数据
+ if not keywords:
+ sql = f"SELECT pid,title,author,r18,tags,urls from main where r18={r18} and status!='unavailable' order by random() limit {num}"
+ elif len(keywords) == 1:
+ sql = f"SELECT pid,title,author,r18,tags,urls from main where (tags like '%{keywords[0]}%' or title like '%{keywords[0]}%' or author like '%{keywords[0]}%') and r18={r18} and status!='unavailable' order by random() limit {num}"
+ else: # 多tag的情况下的sql语句
+ tag_sql = "".join(
+ f"tags like '%{i}%'" if i == keywords[-1] else f"tags like '%{i}%' and "
+ for i in keywords
+ )
+ sql = f"SELECT pid,title,author,r18,tags,urls from main where (({tag_sql}) and r18={r18} and status!='unavailable') order by random() limit {num}"
+ db_data = cur.execute(sql).fetchall()
+ # 断开数据库连接
+ conn.close()
+ # 如果没有返回结果
+ if db_data == []:
+ raise ValueError(f"图库中没有搜到关于{keywords}的图。")
+ # 并发下载图片
+ async with AsyncClient(proxies=config.scientific_agency) as client:
+ tasks = [
+ self.pic(setu, quality, client, pm.read_proxy()) for setu in db_data
+ ]
+ data = await asyncio.gather(*tasks)
+ return data
+
+ async def pic(
+ self, setu: List, quality: int, client: AsyncClient, setu_proxy: str
+ ) -> List: # sourcery skip: low-code-quality
+ """
+ 返回setu消息列表
+ [Error(错误), message(错误信息), False(是否拿到了图), setu_url]
+ 或者
+ [图片(bytes), data(图片信息), True(是否拿到了图), setu_url]
+
+ params: setu: 数据库中的一条数据
+ quality: 图片质量
+ client: httpx的AsyncClient
+ setu_proxy: 反向代理的url
+ """
+
+ setu_pid: int = setu[0] # pid
+ setu_title: str = setu[1] # 标题
+ setu_author: str = setu[2] # 作者
+ setu_r18: str = "True" if setu[3] == 1 else "False" # r18
+ setu_tags: str = setu[4] # 标签
+ setu_url: str = setu[5].replace("i.pixiv.re", setu_proxy) # 图片url
+
+ data = f"标题:{setu_title}\npid:{setu_pid}\n画师:{setu_author}"
+
+ logger.info(f"\n{data}\ntags:{setu_tags}\nR18:{setu_r18}") # 打印信息
+ file_name = setu_url.split("/")[-1] # 获取文件名
+
+ # 判断文件是否本地存在
+ is_nsfw = setu_r18 == "True"
+ # 当不保存的时候, save_path为False, 保存的时候, save_path为路径
+ save_path: Union[bool, str] = (
+ config.setu_nsfw_path if is_nsfw else config.setu_sfw_path
+ )
+ is_in_all_file_name = (
+ file_name in self.all_file_name["nsfw" if is_nsfw else "sfw"]
+ )
+ if is_in_all_file_name:
+ logger.info("图片本地存在")
+ try:
+ image = Image.open(f"{save_path}/{file_name}") # 尝试打开图片
+ except Exception as e:
+ return [
+ "Error",
+ f"本地图片打开失败, 错误信息: {repr(e)}\nfile_name:{file_name}",
+ False,
+ setu_url,
+ ]
+ else:
+ logger.info(f"图片本地不存在,正在去{setu_proxy}下载")
+ content: Union[bytes, int] = await download_pic(setu_url, client)
+ if isinstance(
+ content, int
+ ): # 如果返回的是int, 那么就是状态码, 表示下载失败
+ if (
+ content == 404
+ ): # 如果是404, 404表示文件不存在, 说明作者删除了图片, 那么就把这个url的status改为unavailable, 下次sql操作的时候就不会再拿到这个url了
+ await self.update_status_unavailable(
+ setu[5]
+ ) # setu[5]是原始url, 不能拿换过代理的url
+ logger.error(f"图片下载失败, 状态码: {content}") # 返回错误信息
+ return ["Error", f"图片下载失败, 状态码: {content}", False, setu_url]
+ # 错误处理, 如果content是空bytes, 那么Image.open会报错, 跳到except, 如果能打开图片, 图片应该不成问题,
+ try:
+ image = Image.open(BytesIO(content)) # 打开图片
+ except Exception as e:
+ return ["Error", f"图片打开失败, 错误信息: {repr(e)}", False, setu_url]
+ # 保存图片, 如果save_path不为空, 以及图片不在all_file_name中, 那么就保存图片
+ if save_path:
+ try:
+ with open(f"{save_path}/{file_name}", "wb") as f:
+ f.write(content)
+ self.all_file_name["nsfw" if is_nsfw else "sfw"].add(file_name)
+ except Exception as e:
+ logger.error(f"图片存储失败: {repr(e)}")
+ try:
+ # 尝试修改图片
+ pic = await self.change_pixel(image, quality)
+ return [pic, data, True, setu_url]
+ except Exception as e:
+ return ["Error", f"图片处理失败: {repr(e)}", False, setu_url]
+
+
+# 实例化
+get_data = GetData()
diff --git a/src/plugins/nonebot_plugin_setu4/mamager_handle.py b/src/plugins/nonebot_plugin_setu4/mamager_handle.py
new file mode 100644
index 0000000..e2a0e71
--- /dev/null
+++ b/src/plugins/nonebot_plugin_setu4/mamager_handle.py
@@ -0,0 +1,271 @@
+import os
+import platform
+
+from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message, MessageEvent
+from nonebot.matcher import Matcher
+from nonebot.params import CommandArg
+
+from .fetch_resources import download_database
+from .permission_manager import pm
+from .setu_message import HELP_MSG
+
+
+class ManagerHandle:
+ """
+ 这个类里面是一大堆setu其他指令的handle函数
+ """
+
+ @staticmethod
+ def verify_sid(sid: str) -> bool:
+ """验证会话sid是否合法"""
+ try:
+ stype, sid = sid.split("_")
+ return bool(stype in ["group", "user"] and sid.isdigit())
+ except Exception:
+ return False
+
+ async def open_setu(
+ self, matcher: Matcher, event: MessageEvent, cmd: Message = CommandArg()
+ ) -> None:
+ """
+ 开启或关闭会话的setu功能
+ """
+
+ # 获取命令后面的参数
+ msg = cmd.extract_plain_text().strip()
+ # 分析是新增还是删除
+ if "add" in msg:
+ add_mode = True
+ elif "del" in msg:
+ add_mode = False
+ else:
+ await matcher.finish(
+ f"无效参数: {msg}, 请输入 add 或 del 为参数, eg: add group_114514"
+ )
+
+ if isinstance(event, GroupMessageEvent):
+ sid = f"group_{str(event.group_id)}"
+ else:
+ sid = msg.replace("add", "").replace("del", "").strip()
+ if not self.verify_sid(sid):
+ await matcher.finish(f"无效目标对象: {sid}")
+ await matcher.finish(pm.update_white_list(sid, add_mode))
+
+ async def set_r18(
+ self, matcher: Matcher, event: MessageEvent, cmd: Message = CommandArg()
+ ) -> None:
+ """
+ 开启或关闭会话的r18模式
+ """
+
+ # 获取命令后面的参数
+ msg = cmd.extract_plain_text().strip()
+ # 分析是开启还是关闭
+ if "on" in msg:
+ r18mode = True
+ elif "off" in msg:
+ r18mode = False
+ else:
+ await matcher.finish(
+ f"无效参数: {msg}, 请输入 on 或 off 为参数, eg: on group_114514"
+ )
+ if isinstance(event, GroupMessageEvent):
+ sid = f"group_{str(event.group_id)}"
+ else:
+ sid = msg.replace("on", "").replace("off", "").strip()
+ if not self.verify_sid(sid):
+ await matcher.finish(f"无效目标对象: {sid}")
+ await matcher.finish(pm.update_r18(sid, r18mode))
+
+ async def set_cd(
+ self, matcher: Matcher, event: MessageEvent, cmd: Message = CommandArg()
+ ) -> None:
+ """
+ 获取setu的cd时间
+ """
+
+ # 获取命令后面的参数
+ msg = cmd.extract_plain_text().strip()
+ if msg.isdigit() and isinstance(event, GroupMessageEvent):
+ cd_time = int(msg)
+ sid = f"group_{str(event.group_id)}"
+ await matcher.finish(pm.update_cd(sid, cd_time))
+ else:
+ args = msg.split(" ")
+ if len(args) != 2 or not args[0].isdigit() or not self.verify_sid(args[1]):
+ await matcher.finish(
+ f"无效参数: {msg}, 请输入\n正整数或零 + 空格 + 会话类型_会话id\n为参数\n例如: 0 group_114514"
+ )
+ else:
+ cd_time = int(args[0])
+ sid = args[1]
+ await matcher.finish(pm.update_cd(sid, cd_time))
+
+ async def set_wd(
+ self, matcher: Matcher, event: MessageEvent, cmd: Message = CommandArg()
+ ) -> None:
+ """
+ 获取setu的撤回时间
+ """
+
+ # 获取命令后面的参数
+ msg = cmd.extract_plain_text().strip()
+ if msg.isdigit() and isinstance(event, GroupMessageEvent):
+ wd_time = int(msg)
+ sid = f"group_{str(event.group_id)}"
+ await matcher.finish(pm.update_withdraw_time(sid, wd_time))
+ else:
+ args = msg.split(" ")
+ if len(args) != 2 or not args[0].isdigit() or not self.verify_sid(args[1]):
+ await matcher.finish(
+ f"无效参数: {msg}, 请输入\n正整数 + 空格 + 会话类型_会话id\n为参数\n例如: 100 group_114514"
+ )
+ else:
+ wd_time = int(args[0])
+ sid = args[1]
+ await matcher.finish(pm.update_withdraw_time(sid, wd_time))
+
+ async def set_maxnum(
+ self, matcher: Matcher, event: MessageEvent, cmd: Message = CommandArg()
+ ) -> None:
+ """
+ 获取一次性setu的最大张数
+ """
+
+ # 获取命令后面的参数
+ msg = cmd.extract_plain_text().strip()
+ if msg.isdigit() and isinstance(event, GroupMessageEvent):
+ max_num = int(msg)
+ sid = f"group_{str(event.group_id)}"
+ await matcher.finish(pm.update_max_num(sid, max_num))
+ else:
+ args = msg.split(" ")
+ if len(args) != 2 or not args[0].isdigit() or not self.verify_sid(args[1]):
+ await matcher.finish(
+ f"无效参数: {msg}, 请输入\n正整数 + 空格 + 会话类型_会话id\n为参数\n例如: 10 group_114514"
+ )
+ else:
+ max_num = int(args[0])
+ sid = args[1]
+ await matcher.finish(pm.update_max_num(sid, max_num))
+
+ async def ban_setu(
+ self, matcher: Matcher, event: MessageEvent, cmd: Message = CommandArg()
+ ) -> None:
+ """
+ 开启或关闭会话的setu功能
+ """
+
+ # 获取命令后面的参数
+ msg = cmd.extract_plain_text().strip()
+ # 分析是新增还是删除
+ if "add" in msg:
+ add_mode = True
+ elif "del" in msg:
+ add_mode = False
+ else:
+ await matcher.finish(
+ f"无效参数: {msg}, 请输入 add 或 del 为参数, eg: add group_114514"
+ )
+
+ if isinstance(event, GroupMessageEvent):
+ sid = f"group_{str(event.group_id)}"
+ else:
+ sid = msg.replace("add", "").replace("del", "").strip()
+ if not self.verify_sid(sid):
+ await matcher.finish(f"无效目标对象: {sid}")
+ await matcher.finish(pm.update_ban_list(sid, add_mode))
+
+ @staticmethod
+ async def setu_help(
+ matcher: Matcher,
+ ) -> None:
+ """
+ setu指令帮助
+ """
+
+ await matcher.finish(HELP_MSG)
+
+ @staticmethod
+ async def setu_db(
+ matcher: Matcher,
+ ) -> None:
+ """
+ 拉取数据库
+ """
+
+ await matcher.send(
+ "此功能由于大陆对github的半墙, 国内服务器可能造成数据丢失或无法写入等错误, 不确定性较大, 万一数据库丢失请重新clone"
+ )
+ try:
+ remsg = await download_database()
+ except Exception as e:
+ remsg = f"获取 lolicon.db 失败: {repr(e)}"
+ await matcher.finish(remsg)
+
+ @staticmethod
+ async def query_black_white_list(matcher: Matcher) -> None:
+ """
+ 查新黑白名单
+ """
+
+ res = pm.read_cfg()
+ key_list = list(res.keys()) # 拿到所有的keys
+ for element in ["ban", "last", "proxy"]:
+ if element in key_list:
+ key_list.remove(element)
+ # 黑名单内容则在res['ban']
+ try:
+ await matcher.send(f"白名单: {key_list}\n\n黑名单: {res['ban']}")
+ except KeyError:
+ await matcher.send(f"白名单: {key_list}\n\n黑名单为空")
+
+ @staticmethod
+ async def set_proxy(proxy) -> str:
+ """
+ 设置代理并且ping
+ """
+
+ pm.update_proxy(proxy)
+ plat = platform.system().lower() # 获取系统
+ return (
+ os.popen(f"ping {proxy}").read()
+ if plat == "windows"
+ else os.popen(f"ping -c 4 {proxy}").read()
+ )
+
+ async def replace_proxy_got(self, matcher: Matcher, event: MessageEvent) -> None:
+ """
+ 没参数的情况下
+ """
+
+ msg: str = str(event.get_message()) # 获取消息文本
+ if not msg or msg.isspace():
+ await matcher.finish("需要输入proxy")
+ await matcher.send(f"{msg}已经替换, 正在尝试ping操作验证连通性") # 发送消息
+ result = await self.set_proxy(msg.strip())
+ await matcher.send(
+ f"{result}\n如果丢失的数据比较多, 请考虑重新更换代理"
+ ) # 发送消息
+
+ async def replace_proxy(
+ self, matcher: Matcher, arg: Message = CommandArg()
+ ) -> None:
+ """
+ 有参数的情况
+ """
+
+ msg = arg.extract_plain_text().strip() # 获取消息文本
+ if not msg or msg.isspace():
+ await matcher.pause(
+ f"请输入你要替换的proxy, 当前proxy为:{pm.read_proxy()}\ntips: 一些也许可用的proxy\ni.pixiv.re\nsex.nyan.xyz\npx2.rainchan.win\npximg.moonchan.xyz\npiv.deception.world\npx3.rainchan.win\npx.s.rainchan.win\npixiv.yuki.sh\npixiv.kagarise.workers.dev\nsetu.woshishaluan.top\npixiv.a-f.workers.dev\n等等....\n\neg:px2.rainchan.win\n警告:不要尝试命令行注入其他花里胡哨的东西, 可能会损伤你的电脑"
+ )
+ else:
+ await matcher.send(f"{msg}已经替换, 正在尝试ping操作验证连通性") # 发送消息
+ result = await self.set_proxy(msg)
+ await matcher.finish(
+ f"{result}\n如果丢失的数据比较多, 请考虑重新更换代理"
+ ) # 发送消息
+
+
+manager_handle = ManagerHandle()
diff --git a/src/plugins/nonebot_plugin_setu4/permission_manager.py b/src/plugins/nonebot_plugin_setu4/permission_manager.py
new file mode 100644
index 0000000..3dae15a
--- /dev/null
+++ b/src/plugins/nonebot_plugin_setu4/permission_manager.py
@@ -0,0 +1,363 @@
+import json
+import random
+import time
+
+from loguru import logger
+
+from .config import DATA_PATH, config
+from .setu_message import setu_sendcd
+
+"""
+{
+ 'group_114':{
+ 'cd' : 30, # cd时长
+ 'r18' : True, # r18开关
+ 'withdraw' : 100, # 撤回延时
+ 'maxnum' : 10 # 单次最高张数
+ },
+ 'last':{
+ 'user_1919' : 810 # 最近一次发送setu的时间
+ },
+ 'ban':[
+ 'user_1919', # 禁用的群组或用户,跨会话生效,会覆盖白名单设置
+ 'group_810'
+ ],
+ 'proxy':'i.pixiv.re' # 代理地址
+}
+"""
+
+
+class PermissionManager:
+ def __init__(self) -> None:
+ """
+ 初始化一些配置
+ """
+
+ self.setu_perm_cfg_filepath = DATA_PATH / "setu_perm_cfg.json"
+ self.setu_cd = config.setu_cd
+ self.setu_withdraw_time = config.setu_withdraw_time
+ self.setu_max_num = config.setu_max_num
+ self.setu_disable_wlist = config.setu_disable_wlist
+ self.setu_enable_private = config.setu_enable_private
+ self.group_forward_msg = config.group_forward_msg
+ self.read_cfg()
+
+ def read_cfg(self) -> dict:
+ """
+ 读取配置文件
+ """
+
+ try:
+ # 尝试读取
+ with open(self.setu_perm_cfg_filepath, "r", encoding="utf-8") as f:
+ self.cfg: dict = json.loads(f.read())
+ except Exception as e:
+ # 读取失败
+ logger.warning(f"setu_perm_cfg.json 读取失败, 尝试重建\n{repr(e)}")
+ self.cfg = {"proxy": "i.pixiv.re"}
+ self.write_cfg()
+ return self.cfg
+
+ def write_cfg(self):
+ """
+ 写入配置文件
+ """
+
+ with open(self.setu_perm_cfg_filepath, "w", encoding="utf-8") as f:
+ f.write(json.dumps(self.cfg))
+
+ # --------------- 文件读写 开始 ---------------
+
+ # --------------- 查询系统 开始 ---------------
+ def read_last_send(self, session_id: str) -> float:
+ """
+ 查询最后一次发送时间
+ """
+
+ try:
+ return self.cfg["last"][session_id]
+ except KeyError:
+ return 0
+
+ def read_cd(self, session_id: str) -> int:
+ """
+ 查询cd
+ """
+
+ try:
+ return self.cfg[session_id]["cd"]
+ except KeyError:
+ return self.setu_cd
+
+ def read_withdraw_time(self, session_id: str) -> int:
+ """
+ 查询撤回时间
+ """
+
+ try:
+ return self.cfg[session_id]["withdraw"]
+ except KeyError:
+ return self.setu_withdraw_time
+
+ def read_max_num(self, session_id: str) -> int:
+ """
+ 查询最大张数
+ """
+
+ try:
+ return self.cfg[session_id]["maxnum"]
+ except KeyError:
+ return self.setu_max_num
+
+ def read_r18(self, session_id: str) -> bool:
+ """
+ 查询r18
+ """
+
+ try:
+ return self.cfg[session_id]["r18"]
+ except KeyError:
+ return False
+
+ def read_ban_list(self, session_id: str) -> bool:
+ """
+ 查询黑名单
+ """
+
+ try:
+ return session_id in self.cfg["ban"]
+ except KeyError:
+ return False
+
+ # --------------- 查询系统 结束 ---------------
+
+ # --------------- 逻辑判断 开始 ---------------
+ def check_permission(
+ self, session_id: str, r18flag: bool, num: int, user_type: str = "group"
+ ):
+ """
+ 查询权限, 并返回修正过的参数
+
+ Args:
+ sessionId (str): [会话信息]
+ r18flag (bool): [是否开启r18]
+ num (int): [需求张数]
+ su (bool, optional): [是否为管理员]. Defaults to False.
+
+ Raises:
+ PermissionError: [未在白名单]
+ PermissionError: [cd时间未到]
+
+ Returns:
+ [bool, int, int]: [r18是否启用, 图片张数, 撤回时间]
+ """
+
+ # 优先采用黑名单检查
+ if self.read_ban_list(session_id):
+ logger.warning(f"涩图功能对 {session_id} 禁用!")
+ raise PermissionError(f"涩图功能对 {session_id} 禁用!")
+ # 采用白名单检查, 如果白名单被禁用则跳过
+ if (
+ not self.setu_disable_wlist
+ and (
+ user_type == "group"
+ or ((not self.setu_enable_private) and user_type == "private")
+ )
+ and session_id not in self.cfg.keys()
+ ):
+ logger.warning(f"涩图功能在 {session_id} 会话中未启用")
+ raise PermissionError("涩图功能在此会话中未启用!")
+
+ # 查询冷却时间
+ tile_left = (
+ self.read_cd(session_id) + self.read_last_send(session_id) - time.time()
+ )
+ if tile_left > 0 and user_type != "SU":
+ hours, minutes, seconds = 0, 0, 0
+ if tile_left >= 60:
+ minutes, seconds = divmod(tile_left, 60)
+ hours, minutes = divmod(minutes, 60)
+ else:
+ seconds = tile_left
+ cd_msg = f"{f'{str(round(hours))}小时' if hours else ''}{f'{str(round(minutes))}分钟' if minutes else ''}{f'{str(round(seconds, 3))}秒' if seconds else ''}"
+ logger.warning(f"setu的cd还有{cd_msg}")
+ raise PermissionError(f"{random.choice(setu_sendcd)} 你的CD还有{cd_msg}!")
+
+ # 检查r18权限, 图片张数, 撤回时间
+ r18 = bool(r18flag and self.read_r18(session_id))
+ num_ = (
+ num
+ if num <= self.read_max_num(session_id)
+ else self.read_max_num(session_id)
+ )
+ return r18, num_, self.read_withdraw_time(session_id)
+
+ # --------------- 逻辑判断 结束 ---------------
+
+ # --------------- 冷却更新 开始 ---------------
+ def update_last_send(self, session_id: str):
+ """
+ 更新最后一次发送时间
+ """
+
+ try:
+ self.cfg["last"][session_id] = time.time()
+ except KeyError:
+ self.cfg["last"] = {session_id: time.time()}
+
+ # --------------- 冷却更新 结束 ---------------
+
+ # --------------- 增删系统 开始 ---------------
+ def update_white_list(self, session_id: str, add_mode: bool) -> str:
+ """
+ 更新白名单
+ """
+
+ if add_mode:
+ if session_id in self.cfg.keys():
+ return f"{session_id}已在白名单"
+ self.cfg[session_id] = {}
+ self.write_cfg()
+ return f"成功添加{session_id}至白名单"
+ # 移除出白名单
+ else:
+ if session_id in self.cfg.keys():
+ self.cfg.pop(session_id)
+ self.write_cfg()
+ return f"成功移除{session_id}出白名单"
+ return f"{session_id}不在白名单"
+
+ def update_cd(self, session_id: str, cd_time: int) -> str:
+ """
+ 更新cd时间
+ """
+
+ # 检查是否已在白名单, 不在则结束
+ if session_id not in self.cfg.keys():
+ return f"{session_id}不在白名单, 请先添加至白名单后操作"
+ # 检查数据是否超出范围,超出则设定至范围内
+ cd_time = max(cd_time, 0)
+ # 读取原有数据
+ try:
+ cd_time_old = self.cfg[session_id]["cd"]
+ except Exception:
+ cd_time_old = "未设定"
+ # 写入新数据
+ self.cfg[session_id]["cd"] = cd_time
+ self.write_cfg()
+ # 返回信息
+ return f"成功更新冷却时间 {cd_time_old} -> {cd_time}"
+
+ def update_withdraw_time(self, session_id: str, withdraw_time: int) -> str:
+ """
+ 更新撤回时间
+ """
+
+ # 检查是否已在白名单, 不在则结束
+ if session_id not in self.cfg.keys():
+ return f"{session_id}不在白名单, 请先添加至白名单后操作"
+ # 检查数据是否超出范围,超出则设定至范围内
+ withdraw_time = max(withdraw_time, 0)
+ withdraw_time = min(withdraw_time, 100)
+ # 读取原有数据
+ try:
+ withdraw_time_old = self.cfg[session_id]["withdraw"]
+ except KeyError:
+ withdraw_time_old = "未设定"
+ # 写入新数据
+ self.cfg[session_id]["withdraw"] = withdraw_time
+ self.write_cfg()
+ # 返回信息
+ return f"成功更新撤回时间 {withdraw_time_old} -> {withdraw_time}"
+
+ def update_max_num(self, session_id: str, max_num: int) -> str:
+ """
+ 更新最大张数
+ """
+
+ # 检查是否已在白名单, 不在则结束
+ if session_id not in self.cfg.keys():
+ return f"{session_id}不在白名单, 请先添加至白名单后操作"
+ # 检查数据是否超出范围,超出则设定至范围内
+ max_num = max(max_num, 1)
+ max_num = min(max_num, 25)
+ # 读取原有数据
+ try:
+ max_num_old = self.cfg[session_id]["maxnum"]
+ except KeyError:
+ max_num_old = "未设定"
+ # 写入新数据
+ self.cfg[session_id]["maxnum"] = max_num
+ self.write_cfg()
+ # 返回信息
+ return f"成功更新最大张数 {max_num_old} -> {max_num}"
+
+ def update_r18(self, session_id: str, r18_mode: bool) -> str:
+ # sourcery skip: extract-duplicate-method
+ """
+ 更新r18权限
+ """
+
+ # 检查是否已在白名单, 不在则结束
+ if session_id not in self.cfg.keys():
+ return f"{session_id}不在白名单, 请先添加至白名单后操作"
+
+ if r18_mode:
+ if self.read_r18(session_id):
+ return f"{session_id}已开启r18"
+ self.cfg[session_id]["r18"] = True
+ self.write_cfg()
+ return f"成功开启{session_id}的r18权限"
+ else:
+ if self.read_r18(session_id):
+ self.cfg[session_id]["r18"] = False
+ self.write_cfg()
+ return f"成功关闭{session_id}的r18权限"
+ return f"{session_id}未开启r18"
+
+ def update_ban_list(self, session_id: str, add_mode: bool) -> str:
+ """
+ 更新黑名单
+ """
+
+ if add_mode:
+ try:
+ if session_id in self.cfg["ban"]:
+ return f"{session_id}已在黑名单"
+ except KeyError:
+ self.cfg["ban"] = []
+ self.cfg["ban"].append(session_id)
+ self.write_cfg()
+ return f"成功添加{session_id}至黑名单"
+ # 移出黑名单
+ else:
+ try:
+ self.cfg["ban"].remove(session_id)
+ self.write_cfg()
+ return f"成功移除{session_id}出黑名单"
+ except ValueError:
+ return f"{session_id}不在黑名单"
+
+ def update_proxy(self, proxy: str) -> None:
+ """
+ 更新代理
+ """
+
+ self.cfg["proxy"] = proxy
+ self.write_cfg()
+
+ def read_proxy(self) -> str:
+ """
+ 查询代理
+ """
+
+ try:
+ return self.cfg["proxy"]
+ except KeyError:
+ return "i.pixiv.re"
+
+ # --------------- 增删系统 结束 ---------------
+
+
+# 实例化权限管理
+pm = PermissionManager()
diff --git a/src/plugins/nonebot_plugin_setu4/resource/lolicon.db b/src/plugins/nonebot_plugin_setu4/resource/lolicon.db
new file mode 100644
index 0000000..182b8ba
Binary files /dev/null and b/src/plugins/nonebot_plugin_setu4/resource/lolicon.db differ
diff --git a/src/plugins/nonebot_plugin_setu4/send_setu.py b/src/plugins/nonebot_plugin_setu4/send_setu.py
new file mode 100644
index 0000000..c5711c7
--- /dev/null
+++ b/src/plugins/nonebot_plugin_setu4/send_setu.py
@@ -0,0 +1,178 @@
+import asyncio
+import contextlib
+import random
+import time
+from re import sub
+from typing import Tuple
+
+import nonebot
+from loguru import logger
+from nonebot.adapters.onebot.v11 import (
+ Bot,
+ GroupMessageEvent,
+ Message,
+ MessageEvent,
+ MessageSegment,
+)
+from nonebot.matcher import Matcher
+from nonebot.params import RegexGroup
+
+from .config import config
+from .get_data import get_data
+from .permission_manager import pm
+from .setu_message import setu_sendmessage
+
+
+class SendSetu:
+ def __init__(self) -> None:
+ ...
+ # ⡆⣐⢕⢕⢕⢕⢕⢕⢕⢕⠅⢗⢕⢕⢕⢕⢕⢕⢕⠕⠕⢕⢕⢕⢕⢕⢕⢕⢕⢕
+ # ⢐⢕⢕⢕⢕⢕⣕⢕⢕⠕⠁⢕⢕⢕⢕⢕⢕⢕⢕⠅⡄⢕⢕⢕⢕⢕⢕⢕⢕⢕
+ # ⢕⢕⢕⢕⢕⠅⢗⢕⠕⣠⠄⣗⢕⢕⠕⢕⢕⢕⠕⢠⣿⠐⢕⢕⢕⠑⢕⢕⠵⢕
+ # ⢕⢕⢕⢕⠁⢜⠕⢁⣴⣿⡇⢓⢕⢵⢐⢕⢕⠕⢁⣾⢿⣧⠑⢕⢕⠄⢑⢕⠅⢕
+ # ⢕⢕⠵⢁⠔⢁⣤⣤⣶⣶⣶⡐⣕⢽⠐⢕⠕⣡⣾⣶⣶⣶⣤⡁⢓⢕⠄⢑⢅⢑
+ # ⠍⣧⠄⣶⣾⣿⣿⣿⣿⣿⣿⣷⣔⢕⢄⢡⣾⣿⣿⣿⣿⣿⣿⣿⣦⡑⢕⢤⠱⢐
+ # ⢠⢕⠅⣾⣿⠋⢿⣿⣿⣿⠉⣿⣿⣷⣦⣶⣽⣿⣿⠈⣿⣿⣿⣿⠏⢹⣷⣷⡅⢐
+ # ⣔⢕⢥⢻⣿⡀⠈⠛⠛⠁⢠⣿⣿⣿⣿⣿⣿⣿⣿⡀⠈⠛⠛⠁⠄⣼⣿⣿⡇⢔
+ # ⢕⢕⢽⢸⢟⢟⢖⢖⢤⣶⡟⢻⣿⡿⠻⣿⣿⡟⢀⣿⣦⢤⢤⢔⢞⢿⢿⣿⠁⢕
+ # ⢕⢕⠅⣐⢕⢕⢕⢕⢕⣿⣿⡄⠛⢀⣦⠈⠛⢁⣼⣿⢗⢕⢕⢕⢕⢕⢕⡏⣘⢕
+ # ⢕⢕⠅⢓⣕⣕⣕⣕⣵⣿⣿⣿⣾⣿⣿⣿⣿⣿⣿⣿⣷⣕⢕⢕⢕⢕⡵⢀⢕⢕
+ # ⢑⢕⠃⡈⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢃⢕⢕⢕
+ # ⣆⢕⠄⢱⣄⠛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⢁⢕⢕⠕⢁
+ # ⣿⣦⡀⣿⣿⣷⣶⣬⣍⣛⣛⣛⡛⠿⠿⠿⠛⠛⢛⣛⣉⣭⣤⣂⢜⠕⢑⣡⣴⣿
+
+ @staticmethod
+ def session_id(event: MessageEvent) -> str:
+ """
+ 根据会话类型生成session_id, 一般返回str而不是None, 一般消息事件不是私聊就是群聊
+ """
+
+ if isinstance(event, GroupMessageEvent):
+ return f"group_{str(event.group_id)}"
+ else:
+ return f"user_{str(event.user_id)}"
+
+ @staticmethod
+ async def setu_handle(
+ bot: Bot, matcher: Matcher, event: MessageEvent, args: Tuple = RegexGroup()
+ ) -> None: # sourcery skip: low-code-quality
+ """
+ 发送色图的处理函数
+ """
+
+ # 获取用户输入的参数
+ r18flag = args[2]
+ key = sub("['\"]", "", args[3]) # 去掉引号防止sql注入
+ num = int(sub(r"[张|个|份|x|✖️|×|X|*]", "", args[1])) if args[1] else 1
+
+ # 根据会话类型生成session_id
+ if isinstance(event, GroupMessageEvent):
+ session_id = f"group_{event.group_id}"
+ user_type = "group"
+ else:
+ session_id = f"user_{event.user_id}"
+ user_type = "private"
+
+ # 权限检查
+ try:
+ user_type = (
+ "SU"
+ if (str(event.user_id) in nonebot.get_driver().config.superusers)
+ else user_type
+ )
+ r18, num, withdraw_time = pm.check_permission(
+ session_id, r18flag, num, user_type
+ )
+ except PermissionError as e:
+ await matcher.finish(str(e), at_sender=True)
+ # 检查是否需要撤回, 如果withdraw_time为0 或者 用户在env设置了sfw_withdraw=False切图片非r18时, 那么就不撤回
+ will_withdraw = bool(withdraw_time != 0 and (r18 or config.sfw_withdraw))
+ # quality = 95是最佳质量(图片质量太高发起来太费时间了)
+ quality = 95
+ if num > config.setu_quality[0]:
+ quality = config.setu_quality[1]
+ await matcher.send("由于数量过多请等待片刻")
+
+ # key按照空格切割为数组, 用于多关键词搜索, 并且把数组中的空元素去掉
+ key = [word.strip() for word in key.split(" ") if word.strip()]
+
+ # 控制台输出
+ flag_log = f"\nR18 == {r18}\nkeyword == {key}\nnum == {num}\n"
+ logger.info(f"key = {key}\tr18 = {r18}\tnum = {num}")
+ # 记录时间, 计算CD用
+ pm.update_last_send(session_id)
+
+ # data是数组套娃, 数组中的每个元素内容为: [图片, 信息, True/False, url]
+ try:
+ data = await get_data.get_setu(key, num, r18, quality)
+ except Exception as e:
+ await matcher.finish(repr(e), at_sender=True)
+
+ # 发送的消息列表
+ message_list = []
+ for pic in data:
+ # 如果状态为True,说明图片拿到了
+ if pic[2]:
+ message_list.append(
+ f"{random.choice(setu_sendmessage)}{flag_log}"
+ + Message(pic[1])
+ + MessageSegment.image(pic[0])
+ )
+ flag_log = ""
+ # 状态为false的消息,图片没拿到
+ else:
+ message_list.append(pic[0] + pic[1])
+
+ # 为后面撤回消息做准备
+ setu_msg_id = []
+
+ # 尝试发送
+ try:
+ start_time = time.time() # 记录开始发送的时间
+ # 如果是群聊并且env设置了群聊转发, 那么就转发
+ if isinstance(event, GroupMessageEvent) and pm.group_forward_msg:
+ msgs = [
+ {
+ "type": "node",
+ "data": {
+ "name": "setu-bot",
+ "uin": bot.self_id,
+ "content": msg,
+ },
+ }
+ for msg in message_list
+ ]
+ # 发送转发消息, 并且记录消息id, 撤回用
+ setu_msg_id.append(
+ (
+ await bot.call_api(
+ "send_group_forward_msg",
+ group_id=event.group_id,
+ messages=msgs,
+ )
+ )["message_id"]
+ )
+ else:
+ # 非群聊直接发送
+ for msg in message_list:
+ setu_msg_id.append((await matcher.send(msg))["message_id"])
+ await asyncio.sleep(0.5)
+ except Exception as e:
+ logger.warning(repr(e))
+ await matcher.finish(
+ message=Message(f"消息可能被风控了,图发不出来,错误信息{repr(e)}"),
+ at_sender=True,
+ )
+
+ # 自动撤回涩图
+ if will_withdraw:
+ with contextlib.suppress(Exception):
+ time_left = (
+ withdraw_time + start_time - time.time()
+ ) # 计算从开始发送到目前仍剩余的保留时间
+ await asyncio.sleep(1 if time_left <= 0 else time_left)
+ for msg_id in setu_msg_id:
+ await bot.delete_msg(message_id=msg_id)
+
+
+send_setu = SendSetu()
diff --git a/src/plugins/nonebot_plugin_setu4/setu_message.py b/src/plugins/nonebot_plugin_setu4/setu_message.py
new file mode 100644
index 0000000..ebff8e2
--- /dev/null
+++ b/src/plugins/nonebot_plugin_setu4/setu_message.py
@@ -0,0 +1,52 @@
+setu_sendmessage = [
+ "这是你的🐍图",
+ "喏,图",
+ "给给给个🐍图",
+ "色图有我好冲吗?",
+ "有什么好色图有给发出来让大伙看看!",
+ "没有,有也不给(骗你的~)",
+ "这么喜欢色图呢?不如来点昂昂bot色图?",
+ "hso!",
+ "不许导,积回去!",
+ "∫1/(1+x^4)dx",
+ "注意身体,色图看太多对身体不好",
+]
+setu_sendcd = [
+ "憋住,不准冲!",
+ "你的色图不出来了!",
+ "注意身体,色图看太多对身体不好",
+ "憋再冲了!",
+ "呃...好像冲了好多次...感觉不太好呢...",
+ "这么喜欢bot我, 快来关注昂昂bot -> qq群696748432",
+ "你急啥呢?",
+]
+
+HELP_MSG = r"""setu指令:
+^(setu|色图|涩图|想色色|来份色色|来份色图|想涩涩|多来点|来点色图|来张setu|来张色图|来点色色|色色|涩涩)\s?([x|✖️|×|X|*]?\d+[张|个|份]?)?\s?(r18)?\s?(.*)?
+
+白名单管理:
+setu_wl add 添加会话至白名单 eg: setu_wl add user_114514/group_1919810
+setu_wl del 移出会话自白名单 eg: setu_wl del user_114514/group_1919810
+
+黑名单管理:
+setu_ban add 添加会话至黑名单 eg: setu_ban add user_114514/group_1919810
+setu_ban del 移出会话自黑名单 eg: setu_ban del user_114514/group_1919810
+
+r18模式管理:
+setu_r18 on 开启会话的r18模式 eg: setu_r18 on group_1919810
+setu_r18 off 关闭会话的r18模式 eg: setu_r18 off group_1919810
+
+cd时间更新:
+setu_cd xxx 更新会话的冷却时间, xxx为int类型的参数 eg: setu_cd 10 group_1919810
+
+撤回时间更新:
+setu_wd xxx 撤回前等待的时间, xxx为int类型的参数 eg: setu_wd 10 group_1919810
+
+最大张数更新:
+setu_mn xxx 单次发送的最大图片数, xxx为int类型的参数 eg: setu_mn 10 group_1919810
+
+查询黑白名单:
+setu_roster
+
+更换代理:
+setu_proxy xxx xxx为代理url, 例如i.pixiv.re"""