mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 14:22:55 +08:00
Merge branch 'feature/new-use' of https://github.com/HibiKier/zhenxun_bot into feature/new-use
This commit is contained in:
commit
6e7b6888b1
40
.github/actions/setup-python/action.yml
vendored
Normal file
40
.github/actions/setup-python/action.yml
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
name: Setup Python
|
||||||
|
description: Setup Python
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
python-version:
|
||||||
|
description: Python version
|
||||||
|
required: false
|
||||||
|
default: "3.10"
|
||||||
|
env-dir:
|
||||||
|
description: Environment directory
|
||||||
|
required: false
|
||||||
|
default: "."
|
||||||
|
no-root:
|
||||||
|
description: Do not install package in the environment
|
||||||
|
required: false
|
||||||
|
default: "false"
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Install poetry
|
||||||
|
run: pipx install poetry
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: ${{ inputs.python-version }}
|
||||||
|
cache: "poetry"
|
||||||
|
cache-dependency-path: |
|
||||||
|
./poetry.lock
|
||||||
|
${{ inputs.env-dir }}/poetry.lock
|
||||||
|
|
||||||
|
- run: |
|
||||||
|
cd ${{ inputs.env-dir }}
|
||||||
|
if [ "${{ inputs.no-root }}" = "true" ]; then
|
||||||
|
poetry install --all-extras --no-root
|
||||||
|
else
|
||||||
|
poetry install --all-extras
|
||||||
|
fi
|
||||||
|
shell: bash
|
||||||
11
.github/workflows/linting.yml
vendored
Normal file
11
.github/workflows/linting.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
name: Sequential Lint and Type Check
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ruff-call:
|
||||||
|
uses: ./.github/workflows/ruff.yml
|
||||||
|
|
||||||
|
pyright-call:
|
||||||
|
needs: ruff-call
|
||||||
|
uses: ./.github/workflows/pyright.yml
|
||||||
55
.github/workflows/pyright.yml
vendored
Normal file
55
.github/workflows/pyright.yml
vendored
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
name: Pyright Lint
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
python-version:
|
||||||
|
description: "Python version"
|
||||||
|
required: false
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- "all"
|
||||||
|
- "3.10"
|
||||||
|
- "3.11"
|
||||||
|
- "3.12"
|
||||||
|
default: "all"
|
||||||
|
debug-mode:
|
||||||
|
description: "enable debug mode"
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pyright:
|
||||||
|
name: Pyright Lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
concurrency:
|
||||||
|
group: pyright-${{ github.ref }}-${{ matrix.env }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
env: [pydantic-v1, pydantic-v2]
|
||||||
|
fail-fast: false
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Python environment
|
||||||
|
uses: ./.github/actions/setup-python
|
||||||
|
with:
|
||||||
|
env-dir: ./envs/${{ matrix.env }}
|
||||||
|
no-root: true
|
||||||
|
|
||||||
|
- run: |
|
||||||
|
(cd ./envs/${{ matrix.env }} && echo "$(poetry env info --path)/bin" >> $GITHUB_PATH)
|
||||||
|
if [ "${{ matrix.env }}" = "pydantic-v1" ]; then
|
||||||
|
sed -i 's/PYDANTIC_V2 = true/PYDANTIC_V2 = false/g' ./pyproject.toml
|
||||||
|
fi
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Run Pyright Check
|
||||||
|
uses: jakebailey/pyright-action@v2
|
||||||
|
with:
|
||||||
|
pylance-version: latest-release
|
||||||
20
.github/workflows/ruff.yml
vendored
Normal file
20
.github/workflows/ruff.yml
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
name: Ruff Lint
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ruff:
|
||||||
|
name: Ruff Lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
concurrency:
|
||||||
|
group: ruff-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Install Ruff
|
||||||
|
uses: astral-sh/ruff-action@v3
|
||||||
|
- name: Run Ruff Check
|
||||||
|
run: ruff check
|
||||||
2
.vscode/extensions.json
vendored
2
.vscode/extensions.json
vendored
@ -2,8 +2,6 @@
|
|||||||
"recommendations": [
|
"recommendations": [
|
||||||
"charliermarsh.ruff",
|
"charliermarsh.ruff",
|
||||||
"esbenp.prettier-vscode",
|
"esbenp.prettier-vscode",
|
||||||
"ms-python.black-formatter",
|
|
||||||
"ms-python.isort",
|
|
||||||
"ms-python.python",
|
"ms-python.python",
|
||||||
"ms-python.vscode-pylance"
|
"ms-python.vscode-pylance"
|
||||||
]
|
]
|
||||||
|
|||||||
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
@ -16,6 +16,7 @@
|
|||||||
"jsdelivr",
|
"jsdelivr",
|
||||||
"kaiheila",
|
"kaiheila",
|
||||||
"lolicon",
|
"lolicon",
|
||||||
|
"Mahiro",
|
||||||
"nonebot",
|
"nonebot",
|
||||||
"onebot",
|
"onebot",
|
||||||
"pixiv",
|
"pixiv",
|
||||||
@ -24,19 +25,19 @@
|
|||||||
"tobytes",
|
"tobytes",
|
||||||
"ujson",
|
"ujson",
|
||||||
"unban",
|
"unban",
|
||||||
|
"Uninfo",
|
||||||
"userinfo",
|
"userinfo",
|
||||||
"zhenxun",
|
"zhenxun"
|
||||||
"jsdelivr"
|
|
||||||
],
|
],
|
||||||
"python.analysis.autoImportCompletions": true,
|
"python.analysis.autoImportCompletions": true,
|
||||||
"python.testing.pytestArgs": ["tests"],
|
"python.testing.pytestArgs": ["tests"],
|
||||||
"python.testing.unittestEnabled": false,
|
"python.testing.unittestEnabled": false,
|
||||||
"python.testing.pytestEnabled": true,
|
"python.testing.pytestEnabled": true,
|
||||||
"[python]": {
|
"[python]": {
|
||||||
"editor.defaultFormatter": "charliermarsh.ruff", // 默认使用 Ruff 格式化
|
"editor.defaultFormatter": "charliermarsh.ruff",
|
||||||
"editor.wordBasedSuggestions": "allDocuments",
|
"editor.wordBasedSuggestions": "allDocuments",
|
||||||
"editor.formatOnType": true,
|
"editor.formatOnType": true,
|
||||||
"editor.formatOnSave": true, // 保存时自动格式化
|
"editor.formatOnSave": true,
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.fixAll.ruff": "explicit",
|
"source.fixAll.ruff": "explicit",
|
||||||
"source.organizeImports": "explicit"
|
"source.organizeImports": "explicit"
|
||||||
|
|||||||
@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
<div align=center>
|
<div align=center>
|
||||||
|
|
||||||
[文档](https://hibikier.github.io/zhenxun_bot/)
|
[文档](https://zhenxun-org.github.io/zhenxun_bot/)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ AccessToken: PUBLIC_ZHENXUN_TEST
|
|||||||
- 通过 Config 配置项将所有插件配置统计保存至 config.yaml,利于统一用户修改
|
- 通过 Config 配置项将所有插件配置统计保存至 config.yaml,利于统一用户修改
|
||||||
- 方便增删插件,原生 nonebot2 matcher,不需要额外修改,仅仅通过简单的配置属性就可以生成`帮助图片`和`帮助信息`
|
- 方便增删插件,原生 nonebot2 matcher,不需要额外修改,仅仅通过简单的配置属性就可以生成`帮助图片`和`帮助信息`
|
||||||
- 提供了 cd,阻塞,每日次数等限制,仅仅通过简单的属性就可以生成一个限制,例如:`PluginCdBlock` 等
|
- 提供了 cd,阻塞,每日次数等限制,仅仅通过简单的属性就可以生成一个限制,例如:`PluginCdBlock` 等
|
||||||
- **更多详细请通过 [传送门](https://hibikier.github.io/zhenxun_bot/) 查看文档!**
|
- **更多详细请通过 [传送门](https://zhenxun-org.github.io/zhenxun_bot/) 查看文档!**
|
||||||
|
|
||||||
## 🛠️ 简单部署
|
## 🛠️ 简单部署
|
||||||
|
|
||||||
|
|||||||
67
docker-compose-dev.yml
Normal file
67
docker-compose-dev.yml
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: postgres:15
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: postgres
|
||||||
|
POSTGRES_PASSWORD: password
|
||||||
|
POSTGRES_DB: zhenxun
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
labels:
|
||||||
|
- "prometheus.io/scrape=true"
|
||||||
|
- "prometheus.io/port=9187"
|
||||||
|
|
||||||
|
postgres-exporter:
|
||||||
|
image: prometheuscommunity/postgres-exporter
|
||||||
|
environment:
|
||||||
|
DATA_SOURCE_NAME: "postgresql://postgres:password@db:5432/zhenxun?sslmode=disable"
|
||||||
|
ports:
|
||||||
|
- "9187:9187"
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
labels:
|
||||||
|
- "prometheus.io/scrape=true"
|
||||||
|
- "prometheus.io/port=9121"
|
||||||
|
|
||||||
|
redis-exporter:
|
||||||
|
image: oliver006/redis_exporter
|
||||||
|
environment:
|
||||||
|
REDIS_ADDR: redis://redis:6379
|
||||||
|
ports:
|
||||||
|
- "9121:9121"
|
||||||
|
depends_on:
|
||||||
|
- redis
|
||||||
|
|
||||||
|
prometheus:
|
||||||
|
image: prom/prometheus
|
||||||
|
ports:
|
||||||
|
- "9090:9090"
|
||||||
|
volumes:
|
||||||
|
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
||||||
|
- prometheus_data:/prometheus
|
||||||
|
command:
|
||||||
|
- '--config.file=/etc/prometheus/prometheus.yml'
|
||||||
|
- '--storage.tsdb.path=/prometheus'
|
||||||
|
- '--web.console.libraries=/etc/prometheus/console_libraries'
|
||||||
|
- '--web.console.templates=/etc/prometheus/consoles'
|
||||||
|
|
||||||
|
grafana:
|
||||||
|
image: grafana/grafana
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
volumes:
|
||||||
|
- grafana_data:/var/lib/grafana
|
||||||
|
depends_on:
|
||||||
|
- prometheus
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
|
prometheus_data:
|
||||||
|
grafana_data:
|
||||||
4811
envs/pydantic-v1/poetry.lock
generated
Normal file
4811
envs/pydantic-v1/poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
140
envs/pydantic-v1/pyproject.toml
Normal file
140
envs/pydantic-v1/pyproject.toml
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
[tool.poetry]
|
||||||
|
name = "zhenxun_bot"
|
||||||
|
version = "0.2.4"
|
||||||
|
description = "基于 Nonebot2 和 go-cqhttp 开发,以 postgresql 作为数据库,非常可爱的绪山真寻bot"
|
||||||
|
authors = ["HibiKier <775757368@qq.com>"]
|
||||||
|
license = "AGPL"
|
||||||
|
package-mode = false
|
||||||
|
|
||||||
|
[[tool.poetry.source]]
|
||||||
|
name = "aliyun"
|
||||||
|
url = "https://mirrors.aliyun.com/pypi/simple/"
|
||||||
|
priority = "primary"
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = "^3.10"
|
||||||
|
playwright = "^1.41.1"
|
||||||
|
nonebot-adapter-onebot = "^2.3.1"
|
||||||
|
nonebot-plugin-apscheduler = "^0.5"
|
||||||
|
tortoise-orm = { extras = ["asyncpg"], version = "^0.20.0" }
|
||||||
|
cattrs = "^23.2.3"
|
||||||
|
ruamel-yaml = "^0.18.5"
|
||||||
|
strenum = "^0.4.15"
|
||||||
|
nonebot-plugin-session = "^0.2.3"
|
||||||
|
ujson = "^5.9.0"
|
||||||
|
nb-cli = "^1.3.0"
|
||||||
|
nonebot2 = { extras = ["fastapi"], version = "^2.3.3" }
|
||||||
|
pillow = "^10.0.0"
|
||||||
|
retrying = "^1.3.4"
|
||||||
|
aiofiles = "^23.2.1"
|
||||||
|
nonebot-plugin-htmlrender = ">=0.6.0,<1.0.0"
|
||||||
|
pypinyin = "^0.51.0"
|
||||||
|
beautifulsoup4 = "^4.12.3"
|
||||||
|
lxml = "^5.1.0"
|
||||||
|
psutil = "^5.9.8"
|
||||||
|
feedparser = "^6.0.11"
|
||||||
|
imagehash = "^4.3.1"
|
||||||
|
cn2an = "^0.5.22"
|
||||||
|
dateparser = "^1.2.0"
|
||||||
|
bilireq = "0.2.3post0"
|
||||||
|
python-jose = { extras = ["cryptography"], version = "^3.3.0" }
|
||||||
|
python-multipart = "^0.0.9"
|
||||||
|
aiocache = "^0.12.2"
|
||||||
|
py-cpuinfo = "^9.0.0"
|
||||||
|
nonebot-plugin-alconna = "^0.54.0"
|
||||||
|
tenacity = "^9.0.0"
|
||||||
|
nonebot-plugin-uninfo = ">0.4.1"
|
||||||
|
pydantic = "1.10.18"
|
||||||
|
|
||||||
|
[tool.poetry.group.dev.dependencies]
|
||||||
|
nonebug = "^0.4"
|
||||||
|
pytest-cov = "^5.0.0"
|
||||||
|
pytest-mock = "^3.6.1"
|
||||||
|
pytest-asyncio = "^0.25"
|
||||||
|
pytest-xdist = "^3.3.1"
|
||||||
|
respx = "^0.21.1"
|
||||||
|
ruff = "^0.8.0"
|
||||||
|
pre-commit = "^4.0.0"
|
||||||
|
|
||||||
|
|
||||||
|
[tool.nonebot]
|
||||||
|
plugins = [
|
||||||
|
"nonebot_plugin_apscheduler",
|
||||||
|
"nonebot_plugin_session",
|
||||||
|
"nonebot_plugin_htmlrender",
|
||||||
|
"nonebot_plugin_alconna",
|
||||||
|
]
|
||||||
|
plugin_dirs = ["zhenxun/services", "zhenxun/builtin_plugins", "zhenxun/plugins"]
|
||||||
|
adapters = [
|
||||||
|
{ name = "OneBot V11", module_name = "nonebot.adapters.onebot.v11" },
|
||||||
|
# { name = "DoDo", module_name = "nonebot.adapters.dodo" },
|
||||||
|
# { name = "开黑啦", module_name = "nonebot.adapters.kaiheila" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
line-length = 88
|
||||||
|
target-version = "py310"
|
||||||
|
|
||||||
|
[tool.ruff.format]
|
||||||
|
line-ending = "lf"
|
||||||
|
|
||||||
|
[tool.ruff.lint]
|
||||||
|
select = [
|
||||||
|
"F", # Pyflakes
|
||||||
|
"W", # pycodestyle warnings
|
||||||
|
"E", # pycodestyle errors
|
||||||
|
"I", # isort
|
||||||
|
"UP", # pyupgrade
|
||||||
|
"ASYNC", # flake8-async
|
||||||
|
"C4", # flake8-comprehensions
|
||||||
|
"T10", # flake8-debugger
|
||||||
|
"T20", # flake8-print
|
||||||
|
"PYI", # flake8-pyi
|
||||||
|
"PT", # flake8-pytest-style
|
||||||
|
"Q", # flake8-quotes
|
||||||
|
"TID", # flake8-tidy-imports
|
||||||
|
"RUF", # Ruff-specific rules
|
||||||
|
]
|
||||||
|
ignore = [
|
||||||
|
"E402", # module-import-not-at-top-of-file
|
||||||
|
"UP037", # quoted-annotation
|
||||||
|
"RUF001", # ambiguous-unicode-character-string
|
||||||
|
"RUF002", # ambiguous-unicode-character-docstring
|
||||||
|
"RUF003", # ambiguous-unicode-character-comment
|
||||||
|
"TID252", # relative-imports
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.ruff.lint.isort]
|
||||||
|
force-sort-within-sections = true
|
||||||
|
known-first-party = ["zhenxun", "tests/*"]
|
||||||
|
extra-standard-library = ["typing_extensions"]
|
||||||
|
|
||||||
|
[tool.ruff.lint.flake8-pytest-style]
|
||||||
|
fixture-parentheses = false
|
||||||
|
mark-parentheses = false
|
||||||
|
|
||||||
|
[tool.ruff.lint.pyupgrade]
|
||||||
|
keep-runtime-typing = true
|
||||||
|
|
||||||
|
[tool.pyright]
|
||||||
|
pythonVersion = "3.10"
|
||||||
|
pythonPlatform = "All"
|
||||||
|
defineConstant = { PYDANTIC_V2 = true }
|
||||||
|
executionEnvironments = [
|
||||||
|
{ root = "./tests", extraPaths = [
|
||||||
|
"./",
|
||||||
|
] },
|
||||||
|
{ root = "./" },
|
||||||
|
]
|
||||||
|
|
||||||
|
typeCheckingMode = "standard"
|
||||||
|
reportShadowedImports = false
|
||||||
|
disableBytesTypePromotions = true
|
||||||
|
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
asyncio_mode = "auto"
|
||||||
|
asyncio_default_fixture_loop_scope = "session"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core>=1.0.0"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
||||||
4905
envs/pydantic-v2/poetry.lock
generated
Normal file
4905
envs/pydantic-v2/poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
140
envs/pydantic-v2/pyproject.toml
Normal file
140
envs/pydantic-v2/pyproject.toml
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
[tool.poetry]
|
||||||
|
name = "zhenxun_bot"
|
||||||
|
version = "0.2.4"
|
||||||
|
description = "基于 Nonebot2 和 go-cqhttp 开发,以 postgresql 作为数据库,非常可爱的绪山真寻bot"
|
||||||
|
authors = ["HibiKier <775757368@qq.com>"]
|
||||||
|
license = "AGPL"
|
||||||
|
package-mode = false
|
||||||
|
|
||||||
|
[[tool.poetry.source]]
|
||||||
|
name = "aliyun"
|
||||||
|
url = "https://mirrors.aliyun.com/pypi/simple/"
|
||||||
|
priority = "primary"
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = "^3.10"
|
||||||
|
playwright = "^1.41.1"
|
||||||
|
nonebot-adapter-onebot = "^2.3.1"
|
||||||
|
nonebot-plugin-apscheduler = "^0.5"
|
||||||
|
tortoise-orm = { extras = ["asyncpg"], version = "^0.20.0" }
|
||||||
|
cattrs = "^23.2.3"
|
||||||
|
ruamel-yaml = "^0.18.5"
|
||||||
|
strenum = "^0.4.15"
|
||||||
|
nonebot-plugin-session = "^0.2.3"
|
||||||
|
ujson = "^5.9.0"
|
||||||
|
nb-cli = "^1.3.0"
|
||||||
|
nonebot2 = { extras = ["fastapi"], version = "^2.3.3" }
|
||||||
|
pillow = "^10.0.0"
|
||||||
|
retrying = "^1.3.4"
|
||||||
|
aiofiles = "^23.2.1"
|
||||||
|
nonebot-plugin-htmlrender = ">=0.6.0,<1.0.0"
|
||||||
|
pypinyin = "^0.51.0"
|
||||||
|
beautifulsoup4 = "^4.12.3"
|
||||||
|
lxml = "^5.1.0"
|
||||||
|
psutil = "^5.9.8"
|
||||||
|
feedparser = "^6.0.11"
|
||||||
|
imagehash = "^4.3.1"
|
||||||
|
cn2an = "^0.5.22"
|
||||||
|
dateparser = "^1.2.0"
|
||||||
|
bilireq = "0.2.3post0"
|
||||||
|
python-jose = { extras = ["cryptography"], version = "^3.3.0" }
|
||||||
|
python-multipart = "^0.0.9"
|
||||||
|
aiocache = "^0.12.2"
|
||||||
|
py-cpuinfo = "^9.0.0"
|
||||||
|
nonebot-plugin-alconna = "^0.54.0"
|
||||||
|
tenacity = "^9.0.0"
|
||||||
|
nonebot-plugin-uninfo = ">0.4.1"
|
||||||
|
pydantic = "2.10.6"
|
||||||
|
|
||||||
|
[tool.poetry.group.dev.dependencies]
|
||||||
|
nonebug = "^0.4"
|
||||||
|
pytest-cov = "^5.0.0"
|
||||||
|
pytest-mock = "^3.6.1"
|
||||||
|
pytest-asyncio = "^0.25"
|
||||||
|
pytest-xdist = "^3.3.1"
|
||||||
|
respx = "^0.21.1"
|
||||||
|
ruff = "^0.8.0"
|
||||||
|
pre-commit = "^4.0.0"
|
||||||
|
|
||||||
|
|
||||||
|
[tool.nonebot]
|
||||||
|
plugins = [
|
||||||
|
"nonebot_plugin_apscheduler",
|
||||||
|
"nonebot_plugin_session",
|
||||||
|
"nonebot_plugin_htmlrender",
|
||||||
|
"nonebot_plugin_alconna",
|
||||||
|
]
|
||||||
|
plugin_dirs = ["zhenxun/services", "zhenxun/builtin_plugins", "zhenxun/plugins"]
|
||||||
|
adapters = [
|
||||||
|
{ name = "OneBot V11", module_name = "nonebot.adapters.onebot.v11" },
|
||||||
|
# { name = "DoDo", module_name = "nonebot.adapters.dodo" },
|
||||||
|
# { name = "开黑啦", module_name = "nonebot.adapters.kaiheila" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
line-length = 88
|
||||||
|
target-version = "py310"
|
||||||
|
|
||||||
|
[tool.ruff.format]
|
||||||
|
line-ending = "lf"
|
||||||
|
|
||||||
|
[tool.ruff.lint]
|
||||||
|
select = [
|
||||||
|
"F", # Pyflakes
|
||||||
|
"W", # pycodestyle warnings
|
||||||
|
"E", # pycodestyle errors
|
||||||
|
"I", # isort
|
||||||
|
"UP", # pyupgrade
|
||||||
|
"ASYNC", # flake8-async
|
||||||
|
"C4", # flake8-comprehensions
|
||||||
|
"T10", # flake8-debugger
|
||||||
|
"T20", # flake8-print
|
||||||
|
"PYI", # flake8-pyi
|
||||||
|
"PT", # flake8-pytest-style
|
||||||
|
"Q", # flake8-quotes
|
||||||
|
"TID", # flake8-tidy-imports
|
||||||
|
"RUF", # Ruff-specific rules
|
||||||
|
]
|
||||||
|
ignore = [
|
||||||
|
"E402", # module-import-not-at-top-of-file
|
||||||
|
"UP037", # quoted-annotation
|
||||||
|
"RUF001", # ambiguous-unicode-character-string
|
||||||
|
"RUF002", # ambiguous-unicode-character-docstring
|
||||||
|
"RUF003", # ambiguous-unicode-character-comment
|
||||||
|
"TID252", # relative-imports
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.ruff.lint.isort]
|
||||||
|
force-sort-within-sections = true
|
||||||
|
known-first-party = ["zhenxun", "tests/*"]
|
||||||
|
extra-standard-library = ["typing_extensions"]
|
||||||
|
|
||||||
|
[tool.ruff.lint.flake8-pytest-style]
|
||||||
|
fixture-parentheses = false
|
||||||
|
mark-parentheses = false
|
||||||
|
|
||||||
|
[tool.ruff.lint.pyupgrade]
|
||||||
|
keep-runtime-typing = true
|
||||||
|
|
||||||
|
[tool.pyright]
|
||||||
|
pythonVersion = "3.10"
|
||||||
|
pythonPlatform = "All"
|
||||||
|
defineConstant = { PYDANTIC_V2 = true }
|
||||||
|
executionEnvironments = [
|
||||||
|
{ root = "./tests", extraPaths = [
|
||||||
|
"./",
|
||||||
|
] },
|
||||||
|
{ root = "./" },
|
||||||
|
]
|
||||||
|
|
||||||
|
typeCheckingMode = "standard"
|
||||||
|
reportShadowedImports = false
|
||||||
|
disableBytesTypePromotions = true
|
||||||
|
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
asyncio_mode = "auto"
|
||||||
|
asyncio_default_fixture_loop_scope = "session"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core>=1.0.0"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
||||||
1541
poetry.lock
generated
1541
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
12
prometheus.yml
Normal file
12
prometheus.yml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
global:
|
||||||
|
scrape_interval: 15s
|
||||||
|
evaluation_interval: 15s
|
||||||
|
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: 'postgresql'
|
||||||
|
static_configs:
|
||||||
|
- targets: [ 'postgres-exporter:9187' ]
|
||||||
|
|
||||||
|
- job_name: 'redis'
|
||||||
|
static_configs:
|
||||||
|
- targets: [ 'redis-exporter:9121' ]
|
||||||
@ -45,6 +45,7 @@ nonebot-plugin-alconna = "^0.54.0"
|
|||||||
tenacity = "^9.0.0"
|
tenacity = "^9.0.0"
|
||||||
nonebot-plugin-uninfo = ">0.4.1"
|
nonebot-plugin-uninfo = ">0.4.1"
|
||||||
nonebot-plugin-waiter = "^0.8.1"
|
nonebot-plugin-waiter = "^0.8.1"
|
||||||
|
multidict = ">=6.0.0,!=6.3.2"
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
nonebug = "^0.4"
|
nonebug = "^0.4"
|
||||||
|
|||||||
@ -7,7 +7,7 @@ apscheduler==3.11.0 ; python_version >= "3.10" and python_version < "4.0"
|
|||||||
arclet-alconna-tools==0.7.10 ; python_version >= "3.10" and python_version < "4.0"
|
arclet-alconna-tools==0.7.10 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
arclet-alconna==1.8.35 ; python_version >= "3.10" and python_version < "4.0"
|
arclet-alconna==1.8.35 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
arrow==1.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
arrow==1.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
async-timeout==5.0.1 ; python_version >= "3.10" and python_version < "3.11.0"
|
async-timeout==5.0.1 ; python_version == "3.10"
|
||||||
asyncpg==0.30.0 ; python_version >= "3.10" and python_version < "4.0"
|
asyncpg==0.30.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
attrs==25.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
attrs==25.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
beautifulsoup4==4.13.3 ; python_version >= "3.10" and python_version < "4.0"
|
beautifulsoup4==4.13.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
@ -21,7 +21,7 @@ chardet==5.2.0 ; python_version >= "3.10" and python_version < "4.0"
|
|||||||
charset-normalizer==3.4.1 ; python_version >= "3.10" and python_version < "4.0"
|
charset-normalizer==3.4.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
click==8.1.8 ; python_version >= "3.10" and python_version < "4.0"
|
click==8.1.8 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
cn2an==0.5.23 ; python_version >= "3.10" and python_version < "4.0"
|
cn2an==0.5.23 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
colorama==0.4.6 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "win32" or python_version >= "3.10" and python_version < "4.0" and platform_system == "Windows"
|
colorama==0.4.6 ; python_version >= "3.10" and python_version < "4.0" and (platform_system == "Windows" or sys_platform == "win32")
|
||||||
cookiecutter==2.6.0 ; python_version >= "3.10" and python_version < "4.0"
|
cookiecutter==2.6.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
cryptography==44.0.1 ; python_version >= "3.10" and python_version < "4.0"
|
cryptography==44.0.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
dateparser==1.2.1 ; python_version >= "3.10" and python_version < "4.0"
|
dateparser==1.2.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
@ -60,6 +60,7 @@ nonebot-plugin-session==0.2.3 ; python_version >= "3.10" and python_version < "4
|
|||||||
nonebot-plugin-uninfo==0.6.8 ; python_version >= "3.10" and python_version < "4.0"
|
nonebot-plugin-uninfo==0.6.8 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
nonebot-plugin-waiter==0.8.1 ; python_version >= "3.10" and python_version < "4.0"
|
nonebot-plugin-waiter==0.8.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
nonebot2==2.4.1 ; python_version >= "3.10" and python_version < "4.0"
|
nonebot2==2.4.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
|
nonebot2[fastapi]==2.4.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
noneprompt==0.1.9 ; python_version >= "3.10" and python_version < "4.0"
|
noneprompt==0.1.9 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
numpy==2.2.2 ; python_version >= "3.10" and python_version < "4.0"
|
numpy==2.2.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
pillow==10.4.0 ; python_version >= "3.10" and python_version < "4.0"
|
pillow==10.4.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
@ -81,10 +82,10 @@ pygments==2.19.1 ; python_version >= "3.10" and python_version < "4.0"
|
|||||||
pygtrie==2.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
pygtrie==2.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
pymdown-extensions==10.14.3 ; python_version >= "3.10" and python_version < "4.0"
|
pymdown-extensions==10.14.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
pypika-tortoise==0.1.6 ; python_version >= "3.10" and python_version < "4.0"
|
pypika-tortoise==0.1.6 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
pypinyin==0.51.0 ; python_version >= "3.10" and python_version < "4.0"
|
pypinyin==0.51.0 ; python_version >= "3.10" and python_version < "4"
|
||||||
python-dateutil==2.9.0.post0 ; python_version >= "3.10" and python_version < "4.0"
|
python-dateutil==2.9.0.post0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
python-dotenv==1.0.1 ; python_version >= "3.10" and python_version < "4.0"
|
python-dotenv==1.0.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
python-jose==3.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
python-jose[cryptography]==3.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
python-markdown-math==0.8 ; python_version >= "3.10" and python_version < "4.0"
|
python-markdown-math==0.8 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
python-multipart==0.0.9 ; python_version >= "3.10" and python_version < "4.0"
|
python-multipart==0.0.9 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
python-slugify==8.0.4 ; python_version >= "3.10" and python_version < "4.0"
|
python-slugify==8.0.4 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
@ -94,10 +95,10 @@ pyyaml==6.0.2 ; python_version >= "3.10" and python_version < "4.0"
|
|||||||
regex==2024.11.6 ; python_version >= "3.10" and python_version < "4.0"
|
regex==2024.11.6 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
requests==2.32.3 ; python_version >= "3.10" and python_version < "4.0"
|
requests==2.32.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
retrying==1.3.4 ; python_version >= "3.10" and python_version < "4.0"
|
retrying==1.3.4 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
rfc3986==1.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
rfc3986[idna2008]==1.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
rich==13.9.4 ; python_version >= "3.10" and python_version < "4.0"
|
rich==13.9.4 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
rsa==4.9 ; python_version >= "3.10" and python_version < "4.0"
|
rsa==4.9 ; python_version >= "3.10" and python_version < "4"
|
||||||
ruamel-yaml-clib==0.2.12 ; python_version >= "3.10" and python_version < "3.13" and platform_python_implementation == "CPython"
|
ruamel-yaml-clib==0.2.12 ; platform_python_implementation == "CPython" and python_version < "3.13" and python_version >= "3.10"
|
||||||
ruamel-yaml==0.18.10 ; python_version >= "3.10" and python_version < "4.0"
|
ruamel-yaml==0.18.10 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
scipy==1.15.1 ; python_version >= "3.10" and python_version < "4.0"
|
scipy==1.15.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
sgmllib3k==1.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
sgmllib3k==1.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
@ -109,17 +110,17 @@ strenum==0.4.15 ; python_version >= "3.10" and python_version < "4.0"
|
|||||||
tarina==0.6.8 ; python_version >= "3.10" and python_version < "4.0"
|
tarina==0.6.8 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
tenacity==9.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
tenacity==9.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
text-unidecode==1.3 ; python_version >= "3.10" and python_version < "4.0"
|
text-unidecode==1.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
tomli==2.2.1 ; python_version >= "3.10" and python_version < "3.11"
|
tomli==2.2.1 ; python_version == "3.10"
|
||||||
tomlkit==0.13.2 ; python_version >= "3.10" and python_version < "4.0"
|
tomlkit==0.13.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
tortoise-orm==0.20.1 ; python_version >= "3.10" and python_version < "4.0"
|
tortoise-orm[asyncpg]==0.20.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
types-python-dateutil==2.9.0.20241206 ; python_version >= "3.10" and python_version < "4.0"
|
types-python-dateutil==2.9.0.20241206 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
typing-extensions==4.12.2 ; python_version >= "3.10" and python_version < "4.0"
|
typing-extensions==4.12.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
tzdata==2025.1 ; python_version >= "3.10" and python_version < "4.0" and platform_system == "Windows"
|
tzdata==2025.1 ; python_version >= "3.10" and python_version < "4.0" and platform_system == "Windows"
|
||||||
tzlocal==5.2 ; python_version >= "3.10" and python_version < "4.0"
|
tzlocal==5.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
ujson==5.10.0 ; python_version >= "3.10" and python_version < "4.0"
|
ujson==5.10.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
urllib3==2.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
urllib3==2.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
uvicorn==0.34.0 ; python_version >= "3.10" and python_version < "4.0"
|
uvicorn[standard]==0.34.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
uvloop==0.21.0 ; python_version >= "3.10" and python_version < "4.0" and (sys_platform != "win32" and sys_platform != "cygwin") and platform_python_implementation != "PyPy"
|
uvloop==0.21.0 ; sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy" and python_version >= "3.10" and python_version < "4.0"
|
||||||
virtualenv==20.29.2 ; python_version >= "3.10" and python_version < "4.0"
|
virtualenv==20.29.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
watchfiles==0.24.0 ; python_version >= "3.10" and python_version < "4.0"
|
watchfiles==0.24.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
wcwidth==0.2.13 ; python_version >= "3.10" and python_version < "4.0"
|
wcwidth==0.2.13 ; python_version >= "3.10" and python_version < "4.0"
|
||||||
|
|||||||
@ -15,7 +15,8 @@ async def get_task() -> dict[str, str] | None:
|
|||||||
return {
|
return {
|
||||||
"name": "被动技能",
|
"name": "被动技能",
|
||||||
"description": "控制群组中的被动技能状态",
|
"description": "控制群组中的被动技能状态",
|
||||||
"usage": "通过 开启/关闭群被动 来控制群被<br>----------<br>"
|
"usage": "通过 开启/关闭群被动 来控制群被动 <br>"
|
||||||
|
+ " 示例:开启/关闭群被动早晚安 <br> ---------- <br> "
|
||||||
+ "<br>".join([task.name for task in task_list]),
|
+ "<br>".join([task.name for task in task_list]),
|
||||||
}
|
}
|
||||||
return None
|
return None
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
from zhenxun.configs.path_config import DATA_PATH, IMAGE_PATH
|
from zhenxun.configs.path_config import DATA_PATH, IMAGE_PATH
|
||||||
from zhenxun.models.group_console import GroupConsole
|
from zhenxun.models.group_console import GroupConsole
|
||||||
from zhenxun.models.plugin_info import PluginInfo
|
from zhenxun.models.plugin_info import PluginInfo
|
||||||
@ -14,9 +16,9 @@ GROUP_HELP_PATH = DATA_PATH / "group_help"
|
|||||||
def delete_help_image(gid: str | None = None):
|
def delete_help_image(gid: str | None = None):
|
||||||
"""删除帮助图片"""
|
"""删除帮助图片"""
|
||||||
if gid:
|
if gid:
|
||||||
file = GROUP_HELP_PATH / f"{gid}.png"
|
for file in os.listdir(GROUP_HELP_PATH):
|
||||||
if file.exists():
|
if file.startswith(f"{gid}"):
|
||||||
file.unlink()
|
os.remove(GROUP_HELP_PATH / file)
|
||||||
else:
|
else:
|
||||||
if HELP_FILE.exists():
|
if HELP_FILE.exists():
|
||||||
HELP_FILE.unlink()
|
HELP_FILE.unlink()
|
||||||
@ -196,7 +198,7 @@ class PluginManage:
|
|||||||
await PluginInfo.filter(plugin_type=PluginType.NORMAL).update(
|
await PluginInfo.filter(plugin_type=PluginType.NORMAL).update(
|
||||||
default_status=status
|
default_status=status
|
||||||
)
|
)
|
||||||
return f'成功将所有功能进群默认状态修改为: {"开启" if status else "关闭"}'
|
return f"成功将所有功能进群默认状态修改为: {'开启' if status else '关闭'}"
|
||||||
if group_id:
|
if group_id:
|
||||||
if group := await GroupConsole.get_or_none(
|
if group := await GroupConsole.get_or_none(
|
||||||
group_id=group_id, channel_id__isnull=True
|
group_id=group_id, channel_id__isnull=True
|
||||||
@ -213,12 +215,12 @@ class PluginManage:
|
|||||||
module_list = [f"<{module}" for module in module_list]
|
module_list = [f"<{module}" for module in module_list]
|
||||||
group.block_plugin = ",".join(module_list) + "," # type: ignore
|
group.block_plugin = ",".join(module_list) + "," # type: ignore
|
||||||
await group.save(update_fields=["block_plugin"])
|
await group.save(update_fields=["block_plugin"])
|
||||||
return f'成功将此群组所有功能状态修改为: {"开启" if status else "关闭"}'
|
return f"成功将此群组所有功能状态修改为: {'开启' if status else '关闭'}"
|
||||||
return "获取群组失败..."
|
return "获取群组失败..."
|
||||||
await PluginInfo.filter(plugin_type=PluginType.NORMAL).update(
|
await PluginInfo.filter(plugin_type=PluginType.NORMAL).update(
|
||||||
status=status, block_type=None if status else BlockType.ALL
|
status=status, block_type=None if status else BlockType.ALL
|
||||||
)
|
)
|
||||||
return f'成功将所有功能全局状态修改为: {"开启" if status else "关闭"}'
|
return f"成功将所有功能全局状态修改为: {'开启' if status else '关闭'}"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def is_wake(cls, group_id: str) -> bool:
|
async def is_wake(cls, group_id: str) -> bool:
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
from nonebot import on_message
|
from nonebot import on_message
|
||||||
from nonebot.plugin import PluginMetadata
|
from nonebot.plugin import PluginMetadata
|
||||||
from nonebot_plugin_alconna import UniMsg
|
from nonebot_plugin_alconna import UniMsg
|
||||||
from nonebot_plugin_apscheduler import scheduler
|
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_session import EventSession
|
||||||
|
|
||||||
from zhenxun.configs.config import Config
|
from zhenxun.configs.config import Config
|
||||||
@ -39,45 +38,17 @@ def rule(message: UniMsg) -> bool:
|
|||||||
chat_history = on_message(rule=rule, priority=1, block=False)
|
chat_history = on_message(rule=rule, priority=1, block=False)
|
||||||
|
|
||||||
|
|
||||||
TEMP_LIST = []
|
|
||||||
|
|
||||||
|
|
||||||
@chat_history.handle()
|
@chat_history.handle()
|
||||||
async def _(message: UniMsg, session: EventSession):
|
async def handle_message(message: UniMsg, session: EventSession):
|
||||||
# group_id = session.id3 or session.id2
|
"""处理消息存储"""
|
||||||
group_id = session.id2
|
try:
|
||||||
TEMP_LIST.append(
|
await ChatHistory.create(
|
||||||
ChatHistory(
|
|
||||||
user_id=session.id1,
|
user_id=session.id1,
|
||||||
group_id=group_id,
|
group_id=session.id2,
|
||||||
text=str(message),
|
text=str(message),
|
||||||
plain_text=message.extract_plain_text(),
|
plain_text=message.extract_plain_text(),
|
||||||
bot_id=session.bot_id,
|
bot_id=session.bot_id,
|
||||||
platform=session.platform,
|
platform=session.platform,
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@scheduler.scheduled_job(
|
|
||||||
"interval",
|
|
||||||
minutes=1,
|
|
||||||
)
|
|
||||||
async def _():
|
|
||||||
try:
|
|
||||||
message_list = TEMP_LIST.copy()
|
|
||||||
TEMP_LIST.clear()
|
|
||||||
if message_list:
|
|
||||||
await ChatHistory.bulk_create(message_list)
|
|
||||||
logger.debug(f"批量添加聊天记录 {len(message_list)} 条", "定时任务")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("定时批量添加聊天记录", "定时任务", e=e)
|
logger.warning("存储聊天记录失败", "chat_history", e=e)
|
||||||
|
|
||||||
|
|
||||||
# @test.handle()
|
|
||||||
# async def _(event: MessageEvent):
|
|
||||||
# print(await ChatHistory.get_user_msg(event.user_id, "private"))
|
|
||||||
# print(await ChatHistory.get_user_msg_count(event.user_id, "private"))
|
|
||||||
# print(await ChatHistory.get_user_msg(event.user_id, "group"))
|
|
||||||
# print(await ChatHistory.get_user_msg_count(event.user_id, "group"))
|
|
||||||
# print(await ChatHistory.get_group_msg(event.group_id))
|
|
||||||
# print(await ChatHistory.get_group_msg_count(event.group_id))
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ from datetime import datetime, timedelta
|
|||||||
import inspect
|
import inspect
|
||||||
import time
|
import time
|
||||||
from types import MappingProxyType
|
from types import MappingProxyType
|
||||||
from typing import Any, ClassVar, Literal
|
from typing import Any, Literal
|
||||||
|
|
||||||
from nonebot.adapters import Bot, Event
|
from nonebot.adapters import Bot, Event
|
||||||
from nonebot.compat import model_dump
|
from nonebot.compat import model_dump
|
||||||
@ -69,9 +69,9 @@ class ShopParam(BaseModel):
|
|||||||
"""道具单次使用数量"""
|
"""道具单次使用数量"""
|
||||||
text: str
|
text: str
|
||||||
"""text"""
|
"""text"""
|
||||||
send_success_msg: ClassVar[bool] = True
|
send_success_msg: bool = True
|
||||||
"""是否发送使用成功信息"""
|
"""是否发送使用成功信息"""
|
||||||
max_num_limit: ClassVar[int] = 1
|
max_num_limit: int = 1
|
||||||
"""单次使用最大次数"""
|
"""单次使用最大次数"""
|
||||||
session: Uninfo | None = None
|
session: Uninfo | None = None
|
||||||
"""Uninfo"""
|
"""Uninfo"""
|
||||||
@ -81,7 +81,7 @@ class ShopParam(BaseModel):
|
|||||||
"""At对象"""
|
"""At对象"""
|
||||||
at_users: list[str] = []
|
at_users: list[str] = []
|
||||||
"""At对象列表"""
|
"""At对象列表"""
|
||||||
extra_data: ClassVar[dict[str, Any]] = {}
|
extra_data: dict[str, Any] = Field(default_factory=dict)
|
||||||
"""额外数据"""
|
"""额外数据"""
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
@ -403,10 +403,10 @@ class ShopManage:
|
|||||||
cls.uuid2goods[uuid] = Goods(
|
cls.uuid2goods[uuid] = Goods(
|
||||||
model=create_model(
|
model=create_model(
|
||||||
f"{uuid}_model",
|
f"{uuid}_model",
|
||||||
send_success_msg=send_success_msg,
|
|
||||||
max_num_limit=max_num_limit,
|
|
||||||
__base__=ShopParam,
|
__base__=ShopParam,
|
||||||
extra_data=kwargs,
|
send_success_msg=(bool, Field(default=send_success_msg)),
|
||||||
|
max_num_limit=(int, Field(default=max_num_limit)),
|
||||||
|
extra_data=(dict[str, Any], Field(default=kwargs)),
|
||||||
),
|
),
|
||||||
params=kwargs,
|
params=kwargs,
|
||||||
before_handle=before_handle,
|
before_handle=before_handle,
|
||||||
|
|||||||
@ -15,7 +15,8 @@ async def get_task() -> dict[str, str] | None:
|
|||||||
return {
|
return {
|
||||||
"name": "被动技能",
|
"name": "被动技能",
|
||||||
"description": "控制群组中的被动技能状态",
|
"description": "控制群组中的被动技能状态",
|
||||||
"usage": "通过 开启/关闭群被动 来控制群被动 <br> ---------- <br> "
|
"usage": "通过 开启/关闭群被动 来控制群被动 <br>"
|
||||||
|
+ " 示例:开启/关闭群被动早晚安 <br> ---------- <br> "
|
||||||
+ "<br>".join([task.name for task in task_list]),
|
+ "<br>".join([task.name for task in task_list]),
|
||||||
}
|
}
|
||||||
return None
|
return None
|
||||||
|
|||||||
@ -1,2 +0,0 @@
|
|||||||
from .menu import * # noqa: F403f
|
|
||||||
from .tabs import * # noqa: F403f
|
|
||||||
@ -142,4 +142,4 @@ async def _(query: QueryModel) -> Result[BaseResultModel]:
|
|||||||
async def _(plugin_name: str | None = None) -> Result[dict]:
|
async def _(plugin_name: str | None = None) -> Result[dict]:
|
||||||
if plugin_name:
|
if plugin_name:
|
||||||
return Result.ok(ApiDataSource.SQL_DICT.get(plugin_name))
|
return Result.ok(ApiDataSource.SQL_DICT.get(plugin_name))
|
||||||
return Result.ok(str(ApiDataSource.SQL_DICT))
|
return Result.ok(ApiDataSource.SQL_DICT)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
from typing import Any, overload
|
from typing import Any, cast, overload
|
||||||
from typing_extensions import Self
|
from typing_extensions import Self
|
||||||
|
|
||||||
from tortoise import fields
|
from tortoise import fields
|
||||||
@ -10,6 +10,42 @@ from zhenxun.services.db_context import Model
|
|||||||
from zhenxun.utils.enum import PluginType
|
from zhenxun.utils.enum import PluginType
|
||||||
|
|
||||||
|
|
||||||
|
def add_disable_marker(name: str) -> str:
|
||||||
|
"""添加模块禁用标记符
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: 模块名称
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
添加了禁用标记的模块名 (前缀'<'和后缀',')
|
||||||
|
"""
|
||||||
|
return f"<{name},"
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def convert_module_format(data: str) -> list[str]: ...
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def convert_module_format(data: list[str]) -> str: ...
|
||||||
|
|
||||||
|
|
||||||
|
def convert_module_format(data: str | list[str]) -> str | list[str]:
|
||||||
|
"""
|
||||||
|
在 `<aaa,<bbb,<ccc,` 和 `["aaa", "bbb", "ccc"]` (即禁用启用)之间进行相互转换。
|
||||||
|
|
||||||
|
参数:
|
||||||
|
data: 要转换的数据
|
||||||
|
|
||||||
|
返回:
|
||||||
|
str | list[str]: 根据输入类型返回转换后的数据。
|
||||||
|
"""
|
||||||
|
if isinstance(data, str):
|
||||||
|
return [item.strip(",") for item in data.split("<") if item]
|
||||||
|
else:
|
||||||
|
return "".join(format(item) for item in data)
|
||||||
|
|
||||||
|
|
||||||
class GroupConsole(Model):
|
class GroupConsole(Model):
|
||||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||||
"""自增id"""
|
"""自增id"""
|
||||||
@ -51,33 +87,34 @@ class GroupConsole(Model):
|
|||||||
table_description = "群组信息表"
|
table_description = "群组信息表"
|
||||||
unique_together = ("group_id", "channel_id")
|
unique_together = ("group_id", "channel_id")
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def format(name: str) -> str:
|
|
||||||
return f"<{name},"
|
|
||||||
|
|
||||||
@overload
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def convert_module_format(cls, data: str) -> list[str]: ...
|
async def _get_task_modules(cls, *, default_status: bool) -> list[str]:
|
||||||
|
"""获取默认禁用的任务模块
|
||||||
@overload
|
|
||||||
@classmethod
|
|
||||||
def convert_module_format(cls, data: list[str]) -> str: ...
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def convert_module_format(cls, data: str | list[str]) -> str | list[str]:
|
|
||||||
"""
|
|
||||||
在 `<aaa,<bbb,<ccc,` 和 `["aaa", "bbb", "ccc"]` 之间进行相互转换。
|
|
||||||
|
|
||||||
参数:
|
|
||||||
data (str | list[str]): 输入数据,可能是格式化字符串或字符串列表。
|
|
||||||
|
|
||||||
返回:
|
返回:
|
||||||
str | list[str]: 根据输入类型返回转换后的数据。
|
list[str]: 任务模块列表
|
||||||
"""
|
"""
|
||||||
if isinstance(data, str):
|
return cast(
|
||||||
return [item.strip(",") for item in data.split("<") if item]
|
list[str],
|
||||||
elif isinstance(data, list):
|
await TaskInfo.filter(default_status=default_status).values_list(
|
||||||
return "".join(cls.format(item) for item in data)
|
"module", flat=True
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def _get_plugin_modules(cls, *, default_status: bool) -> list[str]:
|
||||||
|
"""获取默认禁用的插件模块
|
||||||
|
|
||||||
|
返回:
|
||||||
|
list[str]: 插件模块列表
|
||||||
|
"""
|
||||||
|
return cast(
|
||||||
|
list[str],
|
||||||
|
await PluginInfo.filter(
|
||||||
|
plugin_type__in=[PluginType.NORMAL, PluginType.DEPENDANT],
|
||||||
|
default_status=default_status,
|
||||||
|
).values_list("module", flat=True),
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def create(
|
async def create(
|
||||||
@ -85,20 +122,44 @@ class GroupConsole(Model):
|
|||||||
) -> Self:
|
) -> Self:
|
||||||
"""覆盖create方法"""
|
"""覆盖create方法"""
|
||||||
group = await super().create(using_db=using_db, **kwargs)
|
group = await super().create(using_db=using_db, **kwargs)
|
||||||
if modules := await TaskInfo.filter(default_status=False).values_list(
|
|
||||||
"module", flat=True
|
task_modules = await cls._get_task_modules(default_status=False)
|
||||||
):
|
plugin_modules = await cls._get_plugin_modules(default_status=False)
|
||||||
group.block_task = cls.convert_module_format(modules) # type: ignore
|
|
||||||
if modules := await PluginInfo.filter(
|
if task_modules or plugin_modules:
|
||||||
plugin_type__in=[PluginType.NORMAL, PluginType.DEPENDANT],
|
await cls._update_modules(group, task_modules, plugin_modules, using_db)
|
||||||
default_status=False,
|
|
||||||
).values_list("module", flat=True):
|
|
||||||
group.block_plugin = cls.convert_module_format(modules) # type: ignore
|
|
||||||
await group.save(
|
|
||||||
using_db=using_db, update_fields=["block_plugin", "block_task"]
|
|
||||||
)
|
|
||||||
return group
|
return group
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def _update_modules(
|
||||||
|
cls,
|
||||||
|
group: Self,
|
||||||
|
task_modules: list[str],
|
||||||
|
plugin_modules: list[str],
|
||||||
|
using_db: BaseDBAsyncClient | None = None,
|
||||||
|
) -> None:
|
||||||
|
"""更新模块设置
|
||||||
|
|
||||||
|
参数:
|
||||||
|
group: 群组实例
|
||||||
|
task_modules: 任务模块列表
|
||||||
|
plugin_modules: 插件模块列表
|
||||||
|
using_db: 数据库连接
|
||||||
|
"""
|
||||||
|
update_fields = []
|
||||||
|
|
||||||
|
if task_modules:
|
||||||
|
group.block_task = convert_module_format(task_modules)
|
||||||
|
update_fields.append("block_task")
|
||||||
|
|
||||||
|
if plugin_modules:
|
||||||
|
group.block_plugin = convert_module_format(plugin_modules)
|
||||||
|
update_fields.append("block_plugin")
|
||||||
|
|
||||||
|
if update_fields:
|
||||||
|
await group.save(using_db=using_db, update_fields=update_fields)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def get_or_create(
|
async def get_or_create(
|
||||||
cls,
|
cls,
|
||||||
@ -110,20 +171,15 @@ class GroupConsole(Model):
|
|||||||
group, is_create = await super().get_or_create(
|
group, is_create = await super().get_or_create(
|
||||||
defaults=defaults, using_db=using_db, **kwargs
|
defaults=defaults, using_db=using_db, **kwargs
|
||||||
)
|
)
|
||||||
if is_create and (
|
if not is_create:
|
||||||
modules := await TaskInfo.filter(default_status=False).values_list(
|
return group, is_create
|
||||||
"module", flat=True
|
|
||||||
)
|
task_modules = await cls._get_task_modules(default_status=False)
|
||||||
):
|
plugin_modules = await cls._get_plugin_modules(default_status=False)
|
||||||
group.block_task = cls.convert_module_format(modules) # type: ignore
|
|
||||||
if modules := await PluginInfo.filter(
|
if task_modules or plugin_modules:
|
||||||
plugin_type__in=[PluginType.NORMAL, PluginType.DEPENDANT],
|
await cls._update_modules(group, task_modules, plugin_modules, using_db)
|
||||||
default_status=False,
|
|
||||||
).values_list("module", flat=True):
|
|
||||||
group.block_plugin = cls.convert_module_format(modules) # type: ignore
|
|
||||||
await group.save(
|
|
||||||
using_db=using_db, update_fields=["block_plugin", "block_task"]
|
|
||||||
)
|
|
||||||
return group, is_create
|
return group, is_create
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -137,20 +193,15 @@ class GroupConsole(Model):
|
|||||||
group, is_create = await super().update_or_create(
|
group, is_create = await super().update_or_create(
|
||||||
defaults=defaults, using_db=using_db, **kwargs
|
defaults=defaults, using_db=using_db, **kwargs
|
||||||
)
|
)
|
||||||
if is_create and (
|
if not is_create:
|
||||||
modules := await TaskInfo.filter(default_status=False).values_list(
|
return group, is_create
|
||||||
"module", flat=True
|
|
||||||
)
|
task_modules = await cls._get_task_modules(default_status=False)
|
||||||
):
|
plugin_modules = await cls._get_plugin_modules(default_status=False)
|
||||||
group.block_task = cls.convert_module_format(modules) # type: ignore
|
|
||||||
if modules := await PluginInfo.filter(
|
if task_modules or plugin_modules:
|
||||||
plugin_type__in=[PluginType.NORMAL, PluginType.DEPENDANT],
|
await cls._update_modules(group, task_modules, plugin_modules, using_db)
|
||||||
default_status=False,
|
|
||||||
).values_list("module", flat=True):
|
|
||||||
group.block_plugin = cls.convert_module_format(modules) # type: ignore
|
|
||||||
await group.save(
|
|
||||||
using_db=using_db, update_fields=["block_plugin", "block_task"]
|
|
||||||
)
|
|
||||||
return group, is_create
|
return group, is_create
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -195,7 +246,7 @@ class GroupConsole(Model):
|
|||||||
"""
|
"""
|
||||||
return await cls.exists(
|
return await cls.exists(
|
||||||
group_id=group_id,
|
group_id=group_id,
|
||||||
superuser_block_plugin__contains=f"<{module},",
|
superuser_block_plugin__contains=add_disable_marker(module),
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -209,10 +260,11 @@ class GroupConsole(Model):
|
|||||||
返回:
|
返回:
|
||||||
bool: 是否禁用插件
|
bool: 是否禁用插件
|
||||||
"""
|
"""
|
||||||
|
module = add_disable_marker(module)
|
||||||
return await cls.exists(
|
return await cls.exists(
|
||||||
group_id=group_id, block_plugin__contains=f"<{module},"
|
group_id=group_id, block_plugin__contains=module
|
||||||
) or await cls.exists(
|
) or await cls.exists(
|
||||||
group_id=group_id, superuser_block_plugin__contains=f"<{module},"
|
group_id=group_id, superuser_block_plugin__contains=module
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -234,12 +286,22 @@ class GroupConsole(Model):
|
|||||||
group, _ = await cls.get_or_create(
|
group, _ = await cls.get_or_create(
|
||||||
group_id=group_id, defaults={"platform": platform}
|
group_id=group_id, defaults={"platform": platform}
|
||||||
)
|
)
|
||||||
|
update_fields = []
|
||||||
if is_superuser:
|
if is_superuser:
|
||||||
if f"<{module}," not in group.superuser_block_plugin:
|
superuser_block_plugin = convert_module_format(group.superuser_block_plugin)
|
||||||
group.superuser_block_plugin += f"<{module},"
|
if module not in superuser_block_plugin:
|
||||||
elif f"<{module}," not in group.block_plugin:
|
superuser_block_plugin.append(module)
|
||||||
group.block_plugin += f"<{module},"
|
group.superuser_block_plugin = convert_module_format(
|
||||||
await group.save(update_fields=["block_plugin", "superuser_block_plugin"])
|
superuser_block_plugin
|
||||||
|
)
|
||||||
|
update_fields.append("superuser_block_plugin")
|
||||||
|
elif add_disable_marker(module) not in group.block_plugin:
|
||||||
|
block_plugin = convert_module_format(group.block_plugin)
|
||||||
|
block_plugin.append(module)
|
||||||
|
group.block_plugin = convert_module_format(block_plugin)
|
||||||
|
update_fields.append("block_plugin")
|
||||||
|
if update_fields:
|
||||||
|
await group.save(update_fields=update_fields)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def set_unblock_plugin(
|
async def set_unblock_plugin(
|
||||||
@ -260,14 +322,22 @@ class GroupConsole(Model):
|
|||||||
group, _ = await cls.get_or_create(
|
group, _ = await cls.get_or_create(
|
||||||
group_id=group_id, defaults={"platform": platform}
|
group_id=group_id, defaults={"platform": platform}
|
||||||
)
|
)
|
||||||
|
update_fields = []
|
||||||
if is_superuser:
|
if is_superuser:
|
||||||
if f"<{module}," in group.superuser_block_plugin:
|
superuser_block_plugin = convert_module_format(group.superuser_block_plugin)
|
||||||
group.superuser_block_plugin = group.superuser_block_plugin.replace(
|
if module in superuser_block_plugin:
|
||||||
f"<{module},", ""
|
superuser_block_plugin.remove(module)
|
||||||
|
group.superuser_block_plugin = convert_module_format(
|
||||||
|
superuser_block_plugin
|
||||||
)
|
)
|
||||||
elif f"<{module}," in group.block_plugin:
|
update_fields.append("superuser_block_plugin")
|
||||||
group.block_plugin = group.block_plugin.replace(f"<{module},", "")
|
elif add_disable_marker(module) in group.block_plugin:
|
||||||
await group.save(update_fields=["block_plugin", "superuser_block_plugin"])
|
block_plugin = convert_module_format(group.block_plugin)
|
||||||
|
block_plugin.remove(module)
|
||||||
|
group.block_plugin = convert_module_format(block_plugin)
|
||||||
|
update_fields.append("block_plugin")
|
||||||
|
if update_fields:
|
||||||
|
await group.save(update_fields=update_fields)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def is_normal_block_plugin(
|
async def is_normal_block_plugin(
|
||||||
@ -302,7 +372,7 @@ class GroupConsole(Model):
|
|||||||
"""
|
"""
|
||||||
return await cls.exists(
|
return await cls.exists(
|
||||||
group_id=group_id,
|
group_id=group_id,
|
||||||
superuser_block_task__contains=f"<{task},",
|
superuser_block_task__contains=add_disable_marker(task),
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -319,22 +389,23 @@ class GroupConsole(Model):
|
|||||||
返回:
|
返回:
|
||||||
bool: 是否禁用被动
|
bool: 是否禁用被动
|
||||||
"""
|
"""
|
||||||
|
task = add_disable_marker(task)
|
||||||
if not channel_id:
|
if not channel_id:
|
||||||
return await cls.exists(
|
return await cls.exists(
|
||||||
group_id=group_id,
|
group_id=group_id,
|
||||||
channel_id__isnull=True,
|
channel_id__isnull=True,
|
||||||
block_task__contains=f"<{task},",
|
block_task__contains=task,
|
||||||
) or await cls.exists(
|
) or await cls.exists(
|
||||||
group_id=group_id,
|
group_id=group_id,
|
||||||
channel_id__isnull=True,
|
channel_id__isnull=True,
|
||||||
superuser_block_task__contains=f"<{task},",
|
superuser_block_task__contains=task,
|
||||||
)
|
)
|
||||||
return await cls.exists(
|
return await cls.exists(
|
||||||
group_id=group_id, channel_id=channel_id, block_task__contains=f"<{task},"
|
group_id=group_id, channel_id=channel_id, block_task__contains=task
|
||||||
) or await cls.exists(
|
) or await cls.exists(
|
||||||
group_id=group_id,
|
group_id=group_id,
|
||||||
channel_id__isnull=True,
|
channel_id__isnull=True,
|
||||||
superuser_block_task__contains=f"<{task},",
|
superuser_block_task__contains=task,
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -356,12 +427,20 @@ class GroupConsole(Model):
|
|||||||
group, _ = await cls.get_or_create(
|
group, _ = await cls.get_or_create(
|
||||||
group_id=group_id, defaults={"platform": platform}
|
group_id=group_id, defaults={"platform": platform}
|
||||||
)
|
)
|
||||||
|
update_fields = []
|
||||||
if is_superuser:
|
if is_superuser:
|
||||||
if f"<{task}," not in group.superuser_block_task:
|
superuser_block_task = convert_module_format(group.superuser_block_task)
|
||||||
group.superuser_block_task += f"<{task},"
|
if task not in group.superuser_block_task:
|
||||||
elif f"<{task}," not in group.block_task:
|
superuser_block_task.append(task)
|
||||||
group.block_task += f"<{task},"
|
group.superuser_block_task = convert_module_format(superuser_block_task)
|
||||||
await group.save(update_fields=["block_task", "superuser_block_task"])
|
update_fields.append("superuser_block_task")
|
||||||
|
elif add_disable_marker(task) not in group.block_task:
|
||||||
|
block_task = convert_module_format(group.block_task)
|
||||||
|
block_task.append(task)
|
||||||
|
group.block_task = convert_module_format(block_task)
|
||||||
|
update_fields.append("block_task")
|
||||||
|
if update_fields:
|
||||||
|
await group.save(update_fields=update_fields)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def set_unblock_task(
|
async def set_unblock_task(
|
||||||
@ -382,14 +461,20 @@ class GroupConsole(Model):
|
|||||||
group, _ = await cls.get_or_create(
|
group, _ = await cls.get_or_create(
|
||||||
group_id=group_id, defaults={"platform": platform}
|
group_id=group_id, defaults={"platform": platform}
|
||||||
)
|
)
|
||||||
|
update_fields = []
|
||||||
if is_superuser:
|
if is_superuser:
|
||||||
if f"<{task}," in group.superuser_block_task:
|
superuser_block_task = convert_module_format(group.superuser_block_task)
|
||||||
group.superuser_block_task = group.superuser_block_task.replace(
|
if task in superuser_block_task:
|
||||||
f"<{task},", ""
|
superuser_block_task.remove(task)
|
||||||
)
|
group.superuser_block_task = convert_module_format(superuser_block_task)
|
||||||
elif f"<{task}," in group.block_task:
|
update_fields.append("superuser_block_task")
|
||||||
group.block_task = group.block_task.replace(f"<{task},", "")
|
elif add_disable_marker(task) in group.block_task:
|
||||||
await group.save(update_fields=["block_task", "superuser_block_task"])
|
block_task = convert_module_format(group.block_task)
|
||||||
|
block_task.remove(task)
|
||||||
|
group.block_task = convert_module_format(block_task)
|
||||||
|
update_fields.append("block_task")
|
||||||
|
if update_fields:
|
||||||
|
await group.save(update_fields=update_fields)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _run_script(cls):
|
def _run_script(cls):
|
||||||
|
|||||||
@ -64,8 +64,6 @@ class MessageUtils:
|
|||||||
if isinstance(msg, str):
|
if isinstance(msg, str):
|
||||||
if msg.startswith("base64://"):
|
if msg.startswith("base64://"):
|
||||||
message_list.append(Image(raw=BytesIO(base64.b64decode(msg[9:]))))
|
message_list.append(Image(raw=BytesIO(base64.b64decode(msg[9:]))))
|
||||||
elif msg.startswith("http://"):
|
|
||||||
message_list.append(Image(url=msg))
|
|
||||||
else:
|
else:
|
||||||
message_list.append(Text(msg))
|
message_list.append(Text(msg))
|
||||||
elif isinstance(msg, int | float):
|
elif isinstance(msg, int | float):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user