mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 14:22:55 +08:00
✨ 更改冲突
This commit is contained in:
commit
d811eaa3bc
2
.env.dev
2
.env.dev
@ -6,7 +6,7 @@ SESSION_RUNNING_EXPRESSION="别急呀,小真寻要宕机了!QAQ"
|
||||
|
||||
NICKNAME=["真寻", "小真寻", "绪山真寻", "小寻子"]
|
||||
|
||||
SESSION_EXPIRE_TIMEOUT=30
|
||||
SESSION_EXPIRE_TIMEOUT=00:00:30
|
||||
|
||||
ALCONNA_USE_COMMAND_START=True
|
||||
|
||||
|
||||
17
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
17
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -1,8 +1,21 @@
|
||||
name: Bug 反馈
|
||||
title: "Bug: 出现异常"
|
||||
title: "Bug: "
|
||||
description: 提交 Bug 反馈以帮助我们改进代码
|
||||
labels: ["bug"]
|
||||
labels: [ "bug" ]
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: 提交前检查项
|
||||
description: 在提交问题之前,请确认以下事项:
|
||||
options:
|
||||
- label: 我已搜索相关的 issue,但没有找到类似的问题
|
||||
required: true
|
||||
- label: 我已更新到最新版本(包括但不限于真寻本体,插件以及相关依赖),问题仍然存在
|
||||
required: true
|
||||
- label: 我已仔细阅读文档,确认我的配置正确
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: env-os
|
||||
attributes:
|
||||
|
||||
9
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
9
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@ -1,7 +1,7 @@
|
||||
name: 功能建议
|
||||
title: "Feature: 功能描述"
|
||||
description: 提出关于项目新功能的想法
|
||||
labels: ["enhancement"]
|
||||
labels: [ "enhancement" ]
|
||||
body:
|
||||
- type: textarea
|
||||
id: problem
|
||||
@ -18,3 +18,10 @@ body:
|
||||
description: 请说明需要的功能或解决方法
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: 我有能力且愿意为这个功能贡献代码
|
||||
options:
|
||||
- label: 我有能力且愿意为这个功能贡献代码
|
||||
|
||||
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
|
||||
94
.github/workflows/codeql.yml
vendored
Normal file
94
.github/workflows/codeql.yml
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL Code Security Analysis"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
schedule:
|
||||
- cron: '45 21 * * 2'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze (${{ matrix.language }})
|
||||
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||
# - https://gh.io/supported-runners-and-hardware-resources
|
||||
# - https://gh.io/using-larger-runners (GitHub.com only)
|
||||
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||
permissions:
|
||||
# required for all workflows
|
||||
security-events: write
|
||||
|
||||
# required to fetch internal or private CodeQL packs
|
||||
packages: read
|
||||
|
||||
# only required for workflows in private repositories
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- language: python
|
||||
build-mode: none
|
||||
- language: javascript-typescript
|
||||
build-mode: none
|
||||
# CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
|
||||
# Use `c-cpp` to analyze code written in C, C++ or both
|
||||
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
|
||||
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
|
||||
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
|
||||
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
|
||||
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
|
||||
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
# If the analyze step fails for one of the languages you are analyzing with
|
||||
# "We were unable to automatically build your code", modify the matrix above
|
||||
# to set the build mode to "manual" for that language. Then modify this step
|
||||
# to build your code.
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
- if: matrix.build-mode == 'manual'
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'If you are using a "manual" build mode for one or more of the' \
|
||||
'languages you are analyzing, replace this with the commands to build' \
|
||||
'your code, for example:'
|
||||
echo ' make bootstrap'
|
||||
echo ' make release'
|
||||
exit 1
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
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": [
|
||||
"charliermarsh.ruff",
|
||||
"esbenp.prettier-vscode",
|
||||
"ms-python.black-formatter",
|
||||
"ms-python.isort",
|
||||
"ms-python.python",
|
||||
"ms-python.vscode-pylance"
|
||||
]
|
||||
|
||||
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
@ -16,6 +16,7 @@
|
||||
"jsdelivr",
|
||||
"kaiheila",
|
||||
"lolicon",
|
||||
"Mahiro",
|
||||
"nonebot",
|
||||
"onebot",
|
||||
"pixiv",
|
||||
@ -24,19 +25,19 @@
|
||||
"tobytes",
|
||||
"ujson",
|
||||
"unban",
|
||||
"Uninfo",
|
||||
"userinfo",
|
||||
"zhenxun",
|
||||
"jsdelivr"
|
||||
"zhenxun"
|
||||
],
|
||||
"python.analysis.autoImportCompletions": true,
|
||||
"python.testing.pytestArgs": ["tests"],
|
||||
"python.testing.unittestEnabled": false,
|
||||
"python.testing.pytestEnabled": true,
|
||||
"[python]": {
|
||||
"editor.defaultFormatter": "charliermarsh.ruff", // 默认使用 Ruff 格式化
|
||||
"editor.defaultFormatter": "charliermarsh.ruff",
|
||||
"editor.wordBasedSuggestions": "allDocuments",
|
||||
"editor.formatOnType": true,
|
||||
"editor.formatOnSave": true, // 保存时自动格式化
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.ruff": "explicit",
|
||||
"source.organizeImports": "explicit"
|
||||
|
||||
29
README.md
29
README.md
@ -44,7 +44,7 @@
|
||||
|
||||
<div align=center>
|
||||
|
||||
[文档](https://hibikier.github.io/zhenxun_bot/)
|
||||
[文档](https://zhenxun-org.github.io/zhenxun_bot/)
|
||||
|
||||
</div>
|
||||
|
||||
@ -58,7 +58,7 @@
|
||||
|
||||
“真寻是<strong>[椛椛](https://github.com/FloatTech/ZeroBot-Plugin)</strong>的好朋友!”
|
||||
|
||||
🎉喜欢真寻,于是真寻就来了!🎉
|
||||
🎉 喜欢真寻,于是真寻就来了!🎉
|
||||
|
||||
本项目符合 [OneBot](https://github.com/howmanybots/onebot) 标准,可基于以下项目与机器人框架/平台进行交互
|
||||
|
||||
@ -72,6 +72,8 @@
|
||||
|
||||
<div align=center>
|
||||
|
||||
<img width="100%" src="https://starify.komoridevs.icu/api/starify?owner=HibiKier&repo=zhenxun_bot" alt="starify" />
|
||||
|
||||
<img src="https://api.star-history.com/svg?repos=HibiKier/zhenxun_bot&type=Timeline" alt="Star Trend" width="800" />
|
||||
|
||||
</div>
|
||||
@ -105,13 +107,13 @@ AccessToken: PUBLIC_ZHENXUN_TEST
|
||||
|
||||
“不要害怕,你的背后还有千千万万的 <strong>伙伴</strong> 啊!”
|
||||
|
||||
| 项目名称 | 主要用途 | 仓库作者 | 备注 |
|
||||
| :--------------------------------------------------------------------: | :------: | :-------------------------------------------------: | :---------------------------: |
|
||||
| [插件库](https://github.com/zhenxun-org/zhenxun_bot_plugins) | 插件 | [zhenxun-org](https://github.com/zhenxun-org) | 原 plugins 文件夹插件 |
|
||||
| [插件索引库](https://github.com/zhenxun-org/zhenxun_bot_plugins_index) | 插件 | [zhenxun-org](https://github.com/zhenxun-org) | 扩展插件索引库 |
|
||||
| [一键安装](https://github.com/soloxiaoye2022/zhenxun_bot-deploy) | 安装 | [soloxiaoye2022](https://github.com/soloxiaoye2022) | 第三方 |
|
||||
| 项目名称 | 主要用途 | 仓库作者 | 备注 |
|
||||
| :--------------------------------------------------------------------: | :------: | :-------------------------------------------------: | :---------------------------------------------------: |
|
||||
| [插件库](https://github.com/zhenxun-org/zhenxun_bot_plugins) | 插件 | [zhenxun-org](https://github.com/zhenxun-org) | 原 plugins 文件夹插件 |
|
||||
| [插件索引库](https://github.com/zhenxun-org/zhenxun_bot_plugins_index) | 插件 | [zhenxun-org](https://github.com/zhenxun-org) | 扩展插件索引库 |
|
||||
| [一键安装](https://github.com/soloxiaoye2022/zhenxun_bot-deploy) | 安装 | [soloxiaoye2022](https://github.com/soloxiaoye2022) | 第三方 |
|
||||
| [WebUi](https://github.com/HibiKier/zhenxun_bot_webui) | 管理 | [hibikier](https://github.com/HibiKier) | 基于真寻 WebApi 的 webui 实现 [预览](#-webui界面展示) |
|
||||
| [安卓 app(WebUi)](https://github.com/YuS1aN/zhenxun_bot_android_ui) | 安装 | [YuS1aN](https://github.com/YuS1aN) | 第三方 |
|
||||
| [安卓 app(WebUi)](https://github.com/YuS1aN/zhenxun_bot_android_ui) | 安装 | [YuS1aN](https://github.com/YuS1aN) | 第三方 |
|
||||
|
||||
</div>
|
||||
|
||||
@ -122,7 +124,7 @@ AccessToken: PUBLIC_ZHENXUN_TEST
|
||||
- 通过 Config 配置项将所有插件配置统计保存至 config.yaml,利于统一用户修改
|
||||
- 方便增删插件,原生 nonebot2 matcher,不需要额外修改,仅仅通过简单的配置属性就可以生成`帮助图片`和`帮助信息`
|
||||
- 提供了 cd,阻塞,每日次数等限制,仅仅通过简单的属性就可以生成一个限制,例如:`PluginCdBlock` 等
|
||||
- **更多详细请通过 [传送门](https://hibikier.github.io/zhenxun_bot/) 查看文档!**
|
||||
- **更多详细请通过 [传送门](https://zhenxun-org.github.io/zhenxun_bot/) 查看文档!**
|
||||
|
||||
## 🛠️ 简单部署
|
||||
|
||||
@ -138,8 +140,7 @@ pip install poetry # 安装 poetry
|
||||
poetry install # 安装依赖
|
||||
|
||||
# 开始运行
|
||||
poetry shell # 进入虚拟环境
|
||||
python bot.py # 运行机器人
|
||||
poetry run python bot.py
|
||||
```
|
||||
|
||||
## 📝 简单配置
|
||||
@ -156,7 +157,7 @@ python bot.py # 运行机器人
|
||||
|
||||
DB_URL 是基于 Tortoise ORM 的数据库连接字符串,用于指定项目所使用的数据库。以下是 DB_URL 的组成部分以及示例:
|
||||
|
||||
格式为: ```<数据库类型>://<用户名>:<密码>@<主机>:<端口>/<数据库名>?<参数>```
|
||||
格式为: `<数据库类型>://<用户名>:<密码>@<主机>:<端口>/<数据库名>?<参数>`
|
||||
|
||||
- 数据库类型:表示数据库类型,例如 postgres、mysql、sqlite 等。
|
||||
- 用户名:数据库的用户名,例如 root。
|
||||
@ -262,7 +263,7 @@ DB_URL 是基于 Tortoise ORM 的数据库连接字符串,用于指定项目
|
||||
|
||||
(可以告诉我你的 **github** 地址,我偷偷换掉 0v|)
|
||||
|
||||
[shenqi](https://afdian.net/u/fa923a8cfe3d11eba61752540025c377) [A_Kyuu](https://afdian.net/u/b83954fc2c1211eba9eb52540025c377) [疯狂混沌](https://afdian.net/u/789a2f9200cd11edb38352540025c377) [投冥](https://afdian.net/a/144514mm) [茶喵](https://afdian.net/u/fd22382eac4d11ecbfc652540025c377) [AemokpaTNR](https://afdian.net/u/1169bb8c8a9611edb0c152540025c377) [爱发电用户\_wrxn](https://afdian.net/u/4aa03d20db4311ecb1e752540025c377) [qqw](https://afdian.net/u/b71db4e2cc3e11ebb76652540025c377) [溫一壺月光下酒](https://afdian.net/u/ad667a5c650c11ed89bf52540025c377) [伝木](https://afdian.net/u/246b80683f9511edba7552540025c377) [阿奎](https://afdian.net/u/da41f72845d511ed930d52540025c377) [醉梦尘逸](https://afdian.net/u/bc11d2683cd011ed99b552540025c377) [Abc](https://afdian.net/u/870dc10a3cd311ed828852540025c377) [本喵无敌哒](https://afdian.net/u/dffaa9005bc911ebb69b52540025c377) [椎名冬羽](https://afdian.net/u/ca1ebd64395e11ed81b452540025c377) [kaito](https://afdian.net/u/a055e20a498811eab1f052540025c377) [笑柒 XIAO_Q7](https://afdian.net/u/4696db5c529111ec84ea52540025c377) [请问一份爱多少钱](https://afdian.net/u/f57ef6602dbd11ed977f52540025c377) [咸鱼鱼鱼鱼](https://afdian.net/u/8e39b9a400e011ed9f4a52540025c377) [Kafka](https://afdian.net/u/41d66798ef6911ecbc5952540025c377) [墨然](https://afdian.net/u/8aa5874a644d11eb8a6752540025c377) [爱发电用户\_T9e4](https://afdian.net/u/2ad1bb82f3a711eca22852540025c377) [笑柒 XIAO_Q7](https://afdian.net/u/4696db5c529111ec84ea52540025c377) [noahzark](https://afdian.net/a/noahzark) [腊条](https://afdian.net/u/f739c4d69eca11eba94b52540025c377) [ze roller](https://afdian.net/u/0e599e96257211ed805152540025c377) [爱发电用户\_4jrf](https://afdian.net/u/6b2cdcc817c611ed949152540025c377) [爱发电用户\_TBsd](https://afdian.net/u/db638b60217911ed9efd52540025c377) [烟寒若雨](https://afdian.net/u/067bd2161eec11eda62b52540025c377) [ln](https://afdian.net/u/b51914ba1c6611ed8a4e52540025c377) [爱发电用户\_b9S4](https://afdian.net/u/3d8f30581a2911edba6d52540025c377) [爱发电用户\_c58s](https://afdian.net/u/a6ad8dda195e11ed9a4152540025c377) [爱发电用户\_eNr9](https://afdian.net/u/05fdb41c0c9a11ed814952540025c377) [MangataAkihi](https://github.com/Sakuracio) [炀](https://afdian.net/u/69b76e9ec77b11ec874f52540025c377) [爱发电用户\_Bc6j](https://afdian.net/u/8546be24f44111eca64052540025c377) [大魔王](https://github.com/xipesoy) [CopilotLaLaLa](https://github.com/CopilotLaLaLa) [嘿小欧](https://afdian.net/u/daa4bec4f24911ec82e552540025c377) [回忆的秋千](https://afdian.net/u/e315d9c6f14f11ecbeef52540025c377) [十年くん](https://github.com/shinianj) [哇](https://afdian.net/u/9b266244f23911eca19052540025c377) [yajiwa](https://github.com/yajiwa) [爆金币](https://afdian.net/u/0d78879ef23711ecb22452540025c377)...
|
||||
[Zer](https://afdian.com/u/6bccdb2a60b411ec9ad452540025c377) [爱发电用户\_HTjk](https://afdian.com/u/6c7d0208064511ec8d7b52540025c377) [shenghuo2](https://afdian.com/u/bca13286102111eda2a052540025c377) [术樱](https://afdian.com/u/414da63a09a311ec8eb752540025c377) [飞火](https://afdian.com/u/404135f48ed711ec962152540025c377) [shenqi](https://afdian.net/u/fa923a8cfe3d11eba61752540025c377) [A_Kyuu](https://afdian.net/u/b83954fc2c1211eba9eb52540025c377) [疯狂混沌](https://afdian.net/u/789a2f9200cd11edb38352540025c377) [投冥](https://afdian.net/a/144514mm) [茶喵](https://afdian.net/u/fd22382eac4d11ecbfc652540025c377) [AemokpaTNR](https://afdian.net/u/1169bb8c8a9611edb0c152540025c377) [爱发电用户\_wrxn](https://afdian.net/u/4aa03d20db4311ecb1e752540025c377) [qqw](https://afdian.net/u/b71db4e2cc3e11ebb76652540025c377) [溫一壺月光下酒](https://afdian.net/u/ad667a5c650c11ed89bf52540025c377) [伝木](https://afdian.net/u/246b80683f9511edba7552540025c377) [阿奎](https://afdian.net/u/da41f72845d511ed930d52540025c377) [醉梦尘逸](https://afdian.net/u/bc11d2683cd011ed99b552540025c377) [Abc](https://afdian.net/u/870dc10a3cd311ed828852540025c377) [本喵无敌哒](https://afdian.net/u/dffaa9005bc911ebb69b52540025c377) [椎名冬羽](https://afdian.net/u/ca1ebd64395e11ed81b452540025c377) [kaito](https://afdian.net/u/a055e20a498811eab1f052540025c377) [笑柒 XIAO_Q7](https://afdian.net/u/4696db5c529111ec84ea52540025c377) [请问一份爱多少钱](https://afdian.net/u/f57ef6602dbd11ed977f52540025c377) [咸鱼鱼鱼鱼](https://afdian.net/u/8e39b9a400e011ed9f4a52540025c377) [Kafka](https://afdian.net/u/41d66798ef6911ecbc5952540025c377) [墨然](https://afdian.net/u/8aa5874a644d11eb8a6752540025c377) [爱发电用户\_T9e4](https://afdian.net/u/2ad1bb82f3a711eca22852540025c377) [笑柒 XIAO_Q7](https://afdian.net/u/4696db5c529111ec84ea52540025c377) [noahzark](https://afdian.net/a/noahzark) [腊条](https://afdian.net/u/f739c4d69eca11eba94b52540025c377) [ze roller](https://afdian.net/u/0e599e96257211ed805152540025c377) [爱发电用户\_4jrf](https://afdian.net/u/6b2cdcc817c611ed949152540025c377) [爱发电用户\_TBsd](https://afdian.net/u/db638b60217911ed9efd52540025c377) [烟寒若雨](https://afdian.net/u/067bd2161eec11eda62b52540025c377) [ln](https://afdian.net/u/b51914ba1c6611ed8a4e52540025c377) [爱发电用户\_b9S4](https://afdian.net/u/3d8f30581a2911edba6d52540025c377) [爱发电用户\_c58s](https://afdian.net/u/a6ad8dda195e11ed9a4152540025c377) [爱发电用户\_eNr9](https://afdian.net/u/05fdb41c0c9a11ed814952540025c377) [MangataAkihi](https://github.com/Sakuracio) [炀](https://afdian.net/u/69b76e9ec77b11ec874f52540025c377) [爱发电用户\_Bc6j](https://afdian.net/u/8546be24f44111eca64052540025c377) [大魔王](https://github.com/xipesoy) [CopilotLaLaLa](https://github.com/CopilotLaLaLa) [嘿小欧](https://afdian.net/u/daa4bec4f24911ec82e552540025c377) [回忆的秋千](https://afdian.net/u/e315d9c6f14f11ecbeef52540025c377) [十年くん](https://github.com/shinianj) [哇](https://afdian.net/u/9b266244f23911eca19052540025c377) [yajiwa](https://github.com/yajiwa) [爆金币](https://afdian.net/u/0d78879ef23711ecb22452540025c377)...
|
||||
|
||||
## 📜 贡献指南
|
||||
|
||||
@ -325,7 +326,7 @@ Project [zhenxun_bot](https://github.com/users/HibiKier/projects/2)
|
||||
<img src="https://contrib.rocks/image?repo=HibiKier/zhenxun_bot&max=1000" alt="contributors"/>
|
||||
</a>
|
||||
|
||||
## 📸 WebUI界面展示
|
||||
## 📸 WebUI 界面展示
|
||||
|
||||
<div style="display: flex; flex-wrap: wrap; justify-content: space-between;">
|
||||
<div style="width: 48%; margin-bottom: 10px;">
|
||||
|
||||
8
bot.py
8
bot.py
@ -1,8 +1,8 @@
|
||||
import nonebot
|
||||
|
||||
# from nonebot.adapters.discord import Adapter as DiscordAdapter
|
||||
from nonebot.adapters.dodo import Adapter as DoDoAdapter
|
||||
from nonebot.adapters.kaiheila import Adapter as KaiheilaAdapter
|
||||
# from nonebot.adapters.dodo import Adapter as DoDoAdapter
|
||||
# from nonebot.adapters.kaiheila import Adapter as KaiheilaAdapter
|
||||
from nonebot.adapters.onebot.v11 import Adapter as OneBotV11Adapter
|
||||
|
||||
nonebot.init()
|
||||
@ -10,8 +10,8 @@ nonebot.init()
|
||||
|
||||
driver = nonebot.get_driver()
|
||||
driver.register_adapter(OneBotV11Adapter)
|
||||
driver.register_adapter(KaiheilaAdapter)
|
||||
driver.register_adapter(DoDoAdapter)
|
||||
# driver.register_adapter(KaiheilaAdapter)
|
||||
# driver.register_adapter(DoDoAdapter)
|
||||
# driver.register_adapter(DiscordAdapter)
|
||||
|
||||
from zhenxun.services.db_context import disconnect, init
|
||||
|
||||
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"
|
||||
2554
poetry.lock
generated
2554
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' ]
|
||||
@ -15,24 +15,19 @@ priority = "primary"
|
||||
python = "^3.10"
|
||||
playwright = "^1.41.1"
|
||||
nonebot-adapter-onebot = "^2.3.1"
|
||||
nonebot-plugin-apscheduler = "^0.3.0"
|
||||
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"
|
||||
nonebot-adapter-kaiheila = "^0.3.0"
|
||||
nb-cli = "^1.3.0"
|
||||
nonebot2 = "^2.1.3"
|
||||
pydantic = "1.10.18"
|
||||
nonebot-adapter-discord = "^0.1.3"
|
||||
nonebot-adapter-dodo = "^0.1.4"
|
||||
nonebot2 = { extras = ["fastapi"], version = "^2.3.3" }
|
||||
pillow = "^10.0.0"
|
||||
retrying = "^1.3.4"
|
||||
aiofiles = "^23.2.1"
|
||||
nonebot-plugin-htmlrender = "^0.3.0"
|
||||
nonebot-plugin-userinfo = "^0.1.3"
|
||||
nonebot-plugin-htmlrender = ">=0.6.0,<1.0.0"
|
||||
pypinyin = "^0.51.0"
|
||||
beautifulsoup4 = "^4.12.3"
|
||||
lxml = "^5.1.0"
|
||||
@ -46,14 +41,17 @@ python-jose = { extras = ["cryptography"], version = "^3.3.0" }
|
||||
python-multipart = "^0.0.9"
|
||||
aiocache = "^0.12.2"
|
||||
py-cpuinfo = "^9.0.0"
|
||||
nonebot-plugin-uninfo = "^0.4.1"
|
||||
nonebot-plugin-alconna = "^0.54.0"
|
||||
tenacity = "^9.0.0"
|
||||
nonebot-plugin-uninfo = ">0.4.1"
|
||||
nonebot-plugin-waiter = "^0.8.1"
|
||||
multidict = ">=6.0.0,!=6.3.2"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
nonebug = "^0.4"
|
||||
pytest-cov = "^5.0.0"
|
||||
pytest-mock = "^3.6.1"
|
||||
pytest-asyncio = "^0.23.5"
|
||||
pytest-asyncio = "^0.25"
|
||||
pytest-xdist = "^3.3.1"
|
||||
respx = "^0.21.1"
|
||||
ruff = "^0.8.0"
|
||||
@ -65,14 +63,13 @@ plugins = [
|
||||
"nonebot_plugin_apscheduler",
|
||||
"nonebot_plugin_session",
|
||||
"nonebot_plugin_htmlrender",
|
||||
"nonebot_plugin_userinfo",
|
||||
"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" },
|
||||
# { name = "DoDo", module_name = "nonebot.adapters.dodo" },
|
||||
# { name = "开黑啦", module_name = "nonebot.adapters.kaiheila" },
|
||||
]
|
||||
|
||||
[tool.ruff]
|
||||
@ -84,24 +81,24 @@ line-ending = "lf"
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
"F", # Pyflakes
|
||||
"W", # pycodestyle warnings
|
||||
"E", # pycodestyle errors
|
||||
"I", # isort
|
||||
"UP", # pyupgrade
|
||||
"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
|
||||
"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
|
||||
"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
|
||||
|
||||
@ -1,50 +1,49 @@
|
||||
aiocache==0.12.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||
aiofiles==23.2.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
aiosqlite==0.17.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
anyio==4.7.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
annotated-types==0.7.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
anyio==4.8.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
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==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"
|
||||
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"
|
||||
attrs==24.2.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
beautifulsoup4==4.12.3 ; 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"
|
||||
bilireq==0.2.3.post0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
binaryornot==0.4.4 ; python_version >= "3.10" and python_version < "4.0"
|
||||
cachetools==5.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
cashews==7.4.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
cattrs==23.2.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||
certifi==2024.8.30 ; python_version >= "3.10" and python_version < "4.0"
|
||||
certifi==2025.1.31 ; python_version >= "3.10" and python_version < "4.0"
|
||||
cffi==1.17.1 ; python_version >= "3.10" and python_version < "4.0" and platform_python_implementation != "PyPy"
|
||||
chardet==5.2.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
charset-normalizer==3.4.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
click==8.1.7 ; python_version >= "3.10" and python_version < "4.0"
|
||||
cn2an==0.5.22 ; 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"
|
||||
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 (platform_system == "Windows" or sys_platform == "win32")
|
||||
cookiecutter==2.6.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
cryptography==44.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
dateparser==1.2.0 ; 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"
|
||||
distlib==0.3.9 ; python_version >= "3.10" and python_version < "4.0"
|
||||
ecdsa==0.19.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
emoji==2.14.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
exceptiongroup==1.2.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||
fastapi==0.115.6 ; python_version >= "3.10" and python_version < "4.0"
|
||||
fastapi==0.115.8 ; python_version >= "3.10" and python_version < "4.0"
|
||||
feedparser==6.0.11 ; python_version >= "3.10" and python_version < "4.0"
|
||||
filelock==3.16.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
filelock==3.17.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
greenlet==3.1.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
grpcio==1.68.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
grpcio==1.70.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
h11==0.14.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
httpcore==0.16.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||
httptools==0.6.4 ; python_version >= "3.10" and python_version < "4.0"
|
||||
httpx==0.23.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||
idna==3.10 ; python_version >= "3.10" and python_version < "4.0"
|
||||
imagehash==4.3.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
importlib-metadata==8.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
imagehash==4.3.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||
importlib-metadata==8.6.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
iso8601==1.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
jinja2==3.1.4 ; python_version >= "3.10" and python_version < "4.0"
|
||||
jinja2==3.1.5 ; python_version >= "3.10" and python_version < "4.0"
|
||||
loguru==0.7.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||
lxml==5.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
lxml==5.3.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
markdown-it-py==3.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
markdown==3.7 ; python_version >= "3.10" and python_version < "4.0"
|
||||
markupsafe==3.0.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||
@ -53,38 +52,35 @@ msgpack==1.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
multidict==6.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nb-cli==1.4.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nepattern==0.7.7 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot-adapter-discord==0.1.8 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot-adapter-dodo==0.1.4 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot-adapter-kaiheila==0.3.4 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot-adapter-onebot==2.4.6 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot-plugin-alconna==0.54.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot-plugin-apscheduler==0.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot-plugin-htmlrender==0.3.5 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot-plugin-alconna==0.54.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot-plugin-apscheduler==0.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot-plugin-htmlrender==0.6.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot-plugin-session==0.2.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot-plugin-uninfo==0.4.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot-plugin-userinfo==0.1.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot-plugin-waiter==0.8.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot2==2.4.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
nonebot2[fastapi]==2.4.0 ; 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"
|
||||
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"
|
||||
numpy==2.2.0 ; 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"
|
||||
platformdirs==4.3.6 ; python_version >= "3.10" and python_version < "4.0"
|
||||
playwright==1.49.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
playwright==1.50.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
proces==0.1.7 ; python_version >= "3.10" and python_version < "4.0"
|
||||
prompt-toolkit==3.0.48 ; python_version >= "3.10" and python_version < "4.0"
|
||||
prompt-toolkit==3.0.50 ; python_version >= "3.10" and python_version < "4.0"
|
||||
propcache==0.2.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
protobuf==4.25.5 ; python_version >= "3.10" and python_version < "4.0"
|
||||
protobuf==4.25.6 ; python_version >= "3.10" and python_version < "4.0"
|
||||
psutil==5.9.8 ; python_version >= "3.10" and python_version < "4.0"
|
||||
py-cpuinfo==9.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
pyasn1==0.6.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
pycparser==2.22 ; python_version >= "3.10" and python_version < "4.0" and platform_python_implementation != "PyPy"
|
||||
pydantic==1.10.18 ; python_version >= "3.10" and python_version < "4.0"
|
||||
pyee==12.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
pydantic-core==2.27.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||
pydantic==2.10.6 ; python_version >= "3.10" and python_version < "4.0"
|
||||
pyee==12.1.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
pyfiglet==1.0.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||
pygments==2.18.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
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"
|
||||
pymdown-extensions==10.12 ; 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"
|
||||
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"
|
||||
@ -93,7 +89,7 @@ python-jose[cryptography]==3.3.0 ; python_version >= "3.10" and python_version <
|
||||
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-slugify==8.0.4 ; python_version >= "3.10" and python_version < "4.0"
|
||||
pytz==2024.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||
pytz==2025.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
pywavelets==1.8.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
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"
|
||||
@ -103,32 +99,32 @@ 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"
|
||||
rsa==4.9 ; python_version >= "3.10" and python_version < "4"
|
||||
ruamel-yaml-clib==0.2.12 ; platform_python_implementation == "CPython" and python_version < "3.13" and python_version >= "3.10"
|
||||
ruamel-yaml==0.18.6 ; python_version >= "3.10" and python_version < "4.0"
|
||||
scipy==1.14.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
setuptools==75.6.0 ; 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"
|
||||
sgmllib3k==1.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
six==1.17.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
sniffio==1.3.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
soupsieve==2.6 ; python_version >= "3.10" and python_version < "4.0"
|
||||
starlette==0.41.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||
starlette==0.45.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
typing-extensions==4.12.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||
tzdata==2024.2 ; 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"
|
||||
ujson==5.10.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
urllib3==2.2.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||
uvicorn[standard]==0.32.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
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.28.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
urllib3==2.3.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 ; 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"
|
||||
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"
|
||||
websockets==14.1 ; python_version >= "3.10" and python_version < "4.0"
|
||||
websockets==14.2 ; python_version >= "3.10" and python_version < "4.0"
|
||||
win32-setctime==1.2.0 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "win32"
|
||||
yarl==1.18.3 ; python_version >= "3.10" and python_version < "4.0"
|
||||
zipp==3.21.0 ; python_version >= "3.10" and python_version < "4.0"
|
||||
|
||||
@ -3,10 +3,6 @@ import os
|
||||
import re
|
||||
|
||||
import nonebot
|
||||
|
||||
# from nonebot.adapters.discord import Adapter as DiscordAdapter
|
||||
from nonebot.adapters.dodo import Adapter as DoDoAdapter
|
||||
from nonebot.adapters.kaiheila import Adapter as KaiheilaAdapter
|
||||
from nonebot.adapters.onebot.v11 import Adapter as OneBotV11Adapter
|
||||
from nonebot.log import logger
|
||||
|
||||
@ -17,8 +13,6 @@ from zhenxun.services.db_context import disconnect, init
|
||||
driver = nonebot.get_driver()
|
||||
|
||||
driver.register_adapter(OneBotV11Adapter)
|
||||
driver.register_adapter(KaiheilaAdapter)
|
||||
driver.register_adapter(DoDoAdapter)
|
||||
|
||||
|
||||
driver.on_startup(init)
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
from collections import namedtuple
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
import platform
|
||||
@ -25,6 +26,40 @@ cpuinfo_get_cpu_info = {"brand_raw": "Intel(R) Core(TM) i7-10700K"}
|
||||
|
||||
def init_mocker(mocker: MockerFixture, tmp_path: Path):
|
||||
mock_psutil = mocker.patch("zhenxun.builtin_plugins.check.data_source.psutil")
|
||||
|
||||
# Define namedtuples for complex return values
|
||||
CpuFreqs = namedtuple("CpuFreqs", ["current"]) # noqa: PYI024
|
||||
VirtualMemoryInfo = namedtuple("VirtualMemoryInfo", ["used", "total", "percent"]) # noqa: PYI024
|
||||
SwapInfo = namedtuple("SwapInfo", ["used", "total", "percent"]) # noqa: PYI024
|
||||
DiskUsage = namedtuple("DiskUsage", ["used", "total", "free", "percent"]) # noqa: PYI024
|
||||
|
||||
# Set specific return values for psutil methods
|
||||
mock_psutil.cpu_percent.return_value = 1.0 # CPU 使用率
|
||||
mock_psutil.cpu_freq.return_value = CpuFreqs(current=0.0) # CPU 频率
|
||||
mock_psutil.cpu_count.return_value = 1 # CPU 核心数
|
||||
|
||||
# Memory Info
|
||||
mock_psutil.virtual_memory.return_value = VirtualMemoryInfo(
|
||||
used=1 * 1024**3, # 1 GB in bytes for used memory
|
||||
total=1 * 1024**3, # 1 GB in bytes for total memory
|
||||
percent=100.0, # 100% of memory used
|
||||
)
|
||||
|
||||
# Swap Info
|
||||
mock_psutil.swap_memory.return_value = SwapInfo(
|
||||
used=1 * 1024**3, # 1 GB in bytes for used swap space
|
||||
total=1 * 1024**3, # 1 GB in bytes for total swap space
|
||||
percent=100.0, # 100% of swap space used
|
||||
)
|
||||
|
||||
# Disk Usage
|
||||
mock_psutil.disk_usage.return_value = DiskUsage(
|
||||
used=1 * 1024**3, # 1 GB in bytes for used disk space
|
||||
total=1 * 1024**3, # 1 GB in bytes for total disk space
|
||||
free=0, # No free space
|
||||
percent=100.0, # 100% of disk space used
|
||||
)
|
||||
|
||||
mock_cpuinfo = mocker.patch("zhenxun.builtin_plugins.check.data_source.cpuinfo")
|
||||
mock_cpuinfo.get_cpu_info.return_value = cpuinfo_get_cpu_info
|
||||
|
||||
@ -95,28 +130,35 @@ async def test_check(
|
||||
)
|
||||
ctx.receive_event(bot=bot, event=event)
|
||||
ctx.should_ignore_rule(_self_check_matcher)
|
||||
|
||||
data = {
|
||||
"cpu_info": f"{mock_psutil.cpu_percent.return_value}% "
|
||||
+ f"- {mock_psutil.cpu_freq.return_value.current}Ghz "
|
||||
+ f"[{mock_psutil.cpu_count.return_value} core]",
|
||||
"cpu_process": mock_psutil.cpu_percent.return_value,
|
||||
"ram_info": f"{round(mock_psutil.virtual_memory.return_value.used / (1024 ** 3), 1)}" # noqa: E501
|
||||
+ f" / {round(mock_psutil.virtual_memory.return_value.total / (1024 ** 3), 1)}"
|
||||
+ " GB",
|
||||
"ram_process": mock_psutil.virtual_memory.return_value.percent,
|
||||
"swap_info": f"{round(mock_psutil.swap_memory.return_value.used / (1024 ** 3), 1)}" # noqa: E501
|
||||
+ f" / {round(mock_psutil.swap_memory.return_value.total / (1024 ** 3), 1)} GB",
|
||||
"swap_process": mock_psutil.swap_memory.return_value.percent,
|
||||
"disk_info": f"{round(mock_psutil.disk_usage.return_value.used / (1024 ** 3), 1)}" # noqa: E501
|
||||
+ f" / {round(mock_psutil.disk_usage.return_value.total / (1024 ** 3), 1)} GB",
|
||||
"disk_process": mock_psutil.disk_usage.return_value.percent,
|
||||
"brand_raw": cpuinfo_get_cpu_info["brand_raw"],
|
||||
"baidu": "red",
|
||||
"google": "red",
|
||||
"system": f"{platform_uname.system} " f"{platform_uname.release}",
|
||||
"version": __get_version(),
|
||||
"plugin_count": len(nonebot.get_loaded_plugins()),
|
||||
"nickname": BotConfig.self_nickname,
|
||||
}
|
||||
|
||||
mock_template_to_pic.assert_awaited_once_with(
|
||||
template_path=str((mock_template_path_new / "check").absolute()),
|
||||
template_name="main.html",
|
||||
templates={
|
||||
"data": {
|
||||
"cpu_info": "1.0% - 1.0Ghz [1 core]",
|
||||
"cpu_process": 1.0,
|
||||
"ram_info": "1.0 / 1.0 GB",
|
||||
"ram_process": 100.0,
|
||||
"swap_info": "1.0 / 1.0 GB",
|
||||
"swap_process": 100.0,
|
||||
"disk_info": "1.0 / 1.0 GB",
|
||||
"disk_process": 100.0,
|
||||
"brand_raw": cpuinfo_get_cpu_info["brand_raw"],
|
||||
"baidu": "red",
|
||||
"google": "red",
|
||||
"system": f"{platform_uname.system} " f"{platform_uname.release}",
|
||||
"version": __get_version(),
|
||||
"plugin_count": len(nonebot.get_loaded_plugins()),
|
||||
"nickname": BotConfig.self_nickname,
|
||||
}
|
||||
},
|
||||
templates={"data": data},
|
||||
pages={
|
||||
"viewport": {"width": 195, "height": 750},
|
||||
"base_url": f"file://{mock_template_path_new.absolute()}",
|
||||
|
||||
@ -16,8 +16,10 @@ from tests.utils import _v11_group_message_event
|
||||
|
||||
|
||||
@pytest.mark.parametrize("package_api", ["jsd", "gh"])
|
||||
@pytest.mark.parametrize("is_commit", [True, False])
|
||||
async def test_add_plugin_basic(
|
||||
package_api: str,
|
||||
is_commit: bool,
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
@ -40,6 +42,12 @@ async def test_add_plugin_basic(
|
||||
if package_api != "gh":
|
||||
mocked_api["zhenxun_bot_plugins_tree"].respond(404)
|
||||
|
||||
if not is_commit:
|
||||
mocked_api["zhenxun_bot_plugins_commit"].respond(404)
|
||||
mocked_api["zhenxun_bot_plugins_commit_proxy"].respond(404)
|
||||
mocked_api["zhenxun_bot_plugins_index_commit"].respond(404)
|
||||
mocked_api["zhenxun_bot_plugins_index_commit_proxy"].respond(404)
|
||||
|
||||
plugin_id = 1
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
@ -67,15 +75,22 @@ async def test_add_plugin_basic(
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
assert mocked_api["search_image_plugin_file_init"].called
|
||||
if is_commit:
|
||||
assert mocked_api["search_image_plugin_file_init_commit"].called
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
else:
|
||||
assert mocked_api["search_image_plugin_file_init"].called
|
||||
assert mocked_api["basic_plugins_no_commit"].called
|
||||
assert mocked_api["extra_plugins_no_commit"].called
|
||||
assert (mock_base_path / "plugins" / "search_image" / "__init__.py").is_file()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("package_api", ["jsd", "gh"])
|
||||
@pytest.mark.parametrize("is_commit", [True, False])
|
||||
async def test_add_plugin_basic_commit_version(
|
||||
package_api: str,
|
||||
is_commit: bool,
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
@ -98,6 +113,11 @@ async def test_add_plugin_basic_commit_version(
|
||||
if package_api != "gh":
|
||||
mocked_api["zhenxun_bot_plugins_tree_commit"].respond(404)
|
||||
|
||||
if not is_commit:
|
||||
mocked_api["zhenxun_bot_plugins_commit"].respond(404)
|
||||
mocked_api["zhenxun_bot_plugins_commit_proxy"].respond(404)
|
||||
mocked_api["zhenxun_bot_plugins_index_commit"].respond(404)
|
||||
mocked_api["zhenxun_bot_plugins_index_commit_proxy"].respond(404)
|
||||
plugin_id = 3
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
@ -125,19 +145,25 @@ async def test_add_plugin_basic_commit_version(
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
if package_api == "jsd":
|
||||
assert mocked_api["zhenxun_bot_plugins_metadata_commit"].called
|
||||
if package_api == "gh":
|
||||
assert mocked_api["zhenxun_bot_plugins_tree_commit"].called
|
||||
if is_commit:
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
else:
|
||||
assert mocked_api["basic_plugins_no_commit"].called
|
||||
assert mocked_api["extra_plugins_no_commit"].called
|
||||
assert mocked_api["bilibili_sub_plugin_file_init"].called
|
||||
assert (mock_base_path / "plugins" / "bilibili_sub" / "__init__.py").is_file()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("package_api", ["jsd", "gh"])
|
||||
@pytest.mark.parametrize("is_commit", [True, False])
|
||||
async def test_add_plugin_basic_is_not_dir(
|
||||
package_api: str,
|
||||
is_commit: bool,
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
@ -160,6 +186,12 @@ async def test_add_plugin_basic_is_not_dir(
|
||||
if package_api != "gh":
|
||||
mocked_api["zhenxun_bot_plugins_tree"].respond(404)
|
||||
|
||||
if not is_commit:
|
||||
mocked_api["zhenxun_bot_plugins_commit"].respond(404)
|
||||
mocked_api["zhenxun_bot_plugins_commit_proxy"].respond(404)
|
||||
mocked_api["zhenxun_bot_plugins_index_commit"].respond(404)
|
||||
mocked_api["zhenxun_bot_plugins_index_commit_proxy"].respond(404)
|
||||
|
||||
plugin_id = 0
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
@ -187,15 +219,22 @@ async def test_add_plugin_basic_is_not_dir(
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
assert mocked_api["jitang_plugin_file"].called
|
||||
if is_commit:
|
||||
assert mocked_api["jitang_plugin_file_commit"].called
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
else:
|
||||
assert mocked_api["jitang_plugin_file"].called
|
||||
assert mocked_api["basic_plugins_no_commit"].called
|
||||
assert mocked_api["extra_plugins_no_commit"].called
|
||||
assert (mock_base_path / "plugins" / "alapi" / "jitang.py").is_file()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("package_api", ["jsd", "gh"])
|
||||
@pytest.mark.parametrize("is_commit", [True, False])
|
||||
async def test_add_plugin_extra(
|
||||
package_api: str,
|
||||
is_commit: bool,
|
||||
app: App,
|
||||
mocker: MockerFixture,
|
||||
mocked_api: MockRouter,
|
||||
@ -218,6 +257,14 @@ async def test_add_plugin_extra(
|
||||
if package_api != "gh":
|
||||
mocked_api["zhenxun_github_sub_tree"].respond(404)
|
||||
|
||||
if not is_commit:
|
||||
mocked_api["zhenxun_github_sub_commit"].respond(404)
|
||||
mocked_api["zhenxun_github_sub_commit_proxy"].respond(404)
|
||||
mocked_api["zhenxun_bot_plugins_commit"].respond(404)
|
||||
mocked_api["zhenxun_bot_plugins_commit_proxy"].respond(404)
|
||||
mocked_api["zhenxun_bot_plugins_index_commit"].respond(404)
|
||||
mocked_api["zhenxun_bot_plugins_index_commit_proxy"].respond(404)
|
||||
|
||||
plugin_id = 4
|
||||
|
||||
async with app.test_matcher(_matcher) as ctx:
|
||||
@ -245,9 +292,14 @@ async def test_add_plugin_extra(
|
||||
result=None,
|
||||
bot=bot,
|
||||
)
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
assert mocked_api["github_sub_plugin_file_init"].called
|
||||
if is_commit:
|
||||
assert mocked_api["github_sub_plugin_file_init_commit"].called
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
else:
|
||||
assert mocked_api["github_sub_plugin_file_init"].called
|
||||
assert mocked_api["basic_plugins_no_commit"].called
|
||||
assert mocked_api["extra_plugins_no_commit"].called
|
||||
assert (mock_base_path / "plugins" / "github_sub" / "__init__.py").is_file()
|
||||
|
||||
|
||||
|
||||
@ -112,7 +112,7 @@ async def test_plugin_store_fail(
|
||||
|
||||
init_mocked_api(mocked_api=mocked_api)
|
||||
mocked_api.get(
|
||||
"https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins/main/plugins.json",
|
||||
"https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins/b101fbc/plugins.json",
|
||||
name="basic_plugins",
|
||||
).respond(404)
|
||||
|
||||
|
||||
@ -65,7 +65,7 @@ async def test_update_all_plugin_basic_need_update(
|
||||
)
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
assert mocked_api["search_image_plugin_file_init"].called
|
||||
assert mocked_api["search_image_plugin_file_init_commit"].called
|
||||
assert (mock_base_path / "plugins" / "search_image" / "__init__.py").is_file()
|
||||
|
||||
|
||||
|
||||
@ -65,7 +65,7 @@ async def test_update_plugin_basic_need_update(
|
||||
)
|
||||
assert mocked_api["basic_plugins"].called
|
||||
assert mocked_api["extra_plugins"].called
|
||||
assert mocked_api["search_image_plugin_file_init"].called
|
||||
assert mocked_api["search_image_plugin_file_init_commit"].called
|
||||
assert (mock_base_path / "plugins" / "search_image" / "__init__.py").is_file()
|
||||
|
||||
|
||||
|
||||
@ -30,6 +30,10 @@ def init_mocked_api(mocked_api: MockRouter) -> None:
|
||||
"https://data.jsdelivr.com/v1/packages/gh/zhenxun-org/zhenxun_bot_plugins@b101fbc",
|
||||
name="zhenxun_bot_plugins_metadata_commit",
|
||||
).respond(json=get_response_json("zhenxun_bot_plugins_metadata.json"))
|
||||
mocked_api.get(
|
||||
"https://data.jsdelivr.com/v1/packages/gh/xuanerwa/zhenxun_github_sub@f524632f78d27f9893beebdf709e0e7885cd08f1",
|
||||
name="zhenxun_github_sub_metadata_commit",
|
||||
).respond(json=get_response_json("zhenxun_github_sub_metadata.json"))
|
||||
|
||||
# tree
|
||||
mocked_api.get(
|
||||
@ -44,6 +48,10 @@ def init_mocked_api(mocked_api: MockRouter) -> None:
|
||||
"https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins/git/trees/b101fbc?recursive=1",
|
||||
name="zhenxun_bot_plugins_tree_commit",
|
||||
).respond(json=get_response_json("zhenxun_bot_plugins_tree.json"))
|
||||
mocked_api.get(
|
||||
"https://api.github.com/repos/xuanerwa/zhenxun_github_sub/git/trees/f524632f78d27f9893beebdf709e0e7885cd08f1?recursive=1",
|
||||
name="zhenxun_github_sub_tree_commit",
|
||||
).respond(json=get_response_json("zhenxun_github_sub_tree.json"))
|
||||
|
||||
mocked_api.head(
|
||||
"https://raw.githubusercontent.com/",
|
||||
@ -51,36 +59,89 @@ def init_mocked_api(mocked_api: MockRouter) -> None:
|
||||
).respond(200, text="")
|
||||
|
||||
mocked_api.get(
|
||||
"https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins/main/plugins.json",
|
||||
"https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins/b101fbc/plugins.json",
|
||||
name="basic_plugins",
|
||||
).respond(json=get_response_json("basic_plugins.json"))
|
||||
mocked_api.get(
|
||||
"https://cdn.jsdelivr.net/gh/zhenxun-org/zhenxun_bot_plugins@main/plugins.json",
|
||||
"https://cdn.jsdelivr.net/gh/zhenxun-org/zhenxun_bot_plugins@b101fbc/plugins.json",
|
||||
name="basic_plugins_jsdelivr",
|
||||
).respond(200, json=get_response_json("basic_plugins.json"))
|
||||
mocked_api.get(
|
||||
"https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins/main/plugins.json",
|
||||
name="basic_plugins_no_commit",
|
||||
).respond(json=get_response_json("basic_plugins.json"))
|
||||
mocked_api.get(
|
||||
"https://cdn.jsdelivr.net/gh/zhenxun-org/zhenxun_bot_plugins@main/plugins.json",
|
||||
name="basic_plugins_jsdelivr_no_commit",
|
||||
).respond(200, json=get_response_json("basic_plugins.json"))
|
||||
|
||||
mocked_api.get(
|
||||
"https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins_index/index/plugins.json",
|
||||
"https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins_index/2ed61284873c526802752b12a3fd3b5e1a59d948/plugins.json",
|
||||
name="extra_plugins",
|
||||
).respond(200, json=get_response_json("extra_plugins.json"))
|
||||
mocked_api.get(
|
||||
"https://cdn.jsdelivr.net/gh/zhenxun-org/zhenxun_bot_plugins_index@index/plugins.json",
|
||||
"https://cdn.jsdelivr.net/gh/zhenxun-org/zhenxun_bot_plugins_index@2ed61284873c526802752b12a3fd3b5e1a59d948/plugins.json",
|
||||
name="extra_plugins_jsdelivr",
|
||||
).respond(200, json=get_response_json("extra_plugins.json"))
|
||||
mocked_api.get(
|
||||
"https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins_index/index/plugins.json",
|
||||
name="extra_plugins_no_commit",
|
||||
).respond(200, json=get_response_json("extra_plugins.json"))
|
||||
mocked_api.get(
|
||||
"https://cdn.jsdelivr.net/gh/zhenxun-org/zhenxun_bot_plugins_index@index/plugins.json",
|
||||
name="extra_plugins_jsdelivr_no_commit",
|
||||
).respond(200, json=get_response_json("extra_plugins.json"))
|
||||
|
||||
mocked_api.get(
|
||||
"https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins/main/plugins/search_image/__init__.py",
|
||||
name="search_image_plugin_file_init",
|
||||
).respond(content=get_content_bytes("search_image.py"))
|
||||
mocked_api.get(
|
||||
"https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins/b101fbc/plugins/search_image/__init__.py",
|
||||
name="search_image_plugin_file_init_commit",
|
||||
).respond(content=get_content_bytes("search_image.py"))
|
||||
mocked_api.get(
|
||||
"https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins/main/plugins/alapi/jitang.py",
|
||||
name="jitang_plugin_file",
|
||||
).respond(content=get_content_bytes("jitang.py"))
|
||||
mocked_api.get(
|
||||
"https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins/b101fbc/plugins/alapi/jitang.py",
|
||||
name="jitang_plugin_file_commit",
|
||||
).respond(content=get_content_bytes("jitang.py"))
|
||||
mocked_api.get(
|
||||
"https://raw.githubusercontent.com/xuanerwa/zhenxun_github_sub/main/github_sub/__init__.py",
|
||||
name="github_sub_plugin_file_init",
|
||||
).respond(content=get_content_bytes("github_sub.py"))
|
||||
mocked_api.get(
|
||||
"https://raw.githubusercontent.com/xuanerwa/zhenxun_github_sub/f524632f78d27f9893beebdf709e0e7885cd08f1/github_sub/__init__.py",
|
||||
name="github_sub_plugin_file_init_commit",
|
||||
).respond(content=get_content_bytes("github_sub.py"))
|
||||
mocked_api.get(
|
||||
"https://raw.githubusercontent.com/zhenxun-org/zhenxun_bot_plugins/b101fbc/plugins/bilibili_sub/__init__.py",
|
||||
name="bilibili_sub_plugin_file_init",
|
||||
).respond(content=get_content_bytes("bilibili_sub.py"))
|
||||
|
||||
mocked_api.get(
|
||||
"https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins/commits/main",
|
||||
name="zhenxun_bot_plugins_commit",
|
||||
).respond(json=get_response_json("zhenxun_bot_plugins_commit.json"))
|
||||
mocked_api.get(
|
||||
"https://git-api.zhenxun.org/repos/zhenxun-org/zhenxun_bot_plugins/commits/main",
|
||||
name="zhenxun_bot_plugins_commit_proxy",
|
||||
).respond(json=get_response_json("zhenxun_bot_plugins_commit.json"))
|
||||
mocked_api.get(
|
||||
"https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins_index/commits/index",
|
||||
name="zhenxun_bot_plugins_index_commit",
|
||||
).respond(json=get_response_json("zhenxun_bot_plugins_index_commit.json"))
|
||||
mocked_api.get(
|
||||
"https://git-api.zhenxun.org/repos/zhenxun-org/zhenxun_bot_plugins_index/commits/index",
|
||||
name="zhenxun_bot_plugins_index_commit_proxy",
|
||||
).respond(json=get_response_json("zhenxun_bot_plugins_index_commit.json"))
|
||||
mocked_api.get(
|
||||
"https://api.github.com/repos/xuanerwa/zhenxun_github_sub/commits/main",
|
||||
name="zhenxun_github_sub_commit",
|
||||
).respond(json=get_response_json("zhenxun_github_sub_commit.json"))
|
||||
mocked_api.get(
|
||||
"https://git-api.zhenxun.org/repos/xuanerwa/zhenxun_github_sub/commits/main",
|
||||
name="zhenxun_github_sub_commit_proxy",
|
||||
).respond(json=get_response_json("zhenxun_github_sub_commit.json"))
|
||||
|
||||
@ -12,7 +12,7 @@ from pytest_asyncio import is_async_test
|
||||
from pytest_mock import MockerFixture
|
||||
from respx import MockRouter
|
||||
|
||||
from tests.config import BotId, UserId
|
||||
from tests.config import BotId, GroupId, UserId
|
||||
|
||||
nonebot.load_plugin("nonebot_plugin_session")
|
||||
|
||||
@ -47,7 +47,7 @@ def pytest_configure(config: pytest.Config) -> None:
|
||||
},
|
||||
"host": "127.0.0.1",
|
||||
"port": 8080,
|
||||
"log_level": "DEBUG",
|
||||
"log_level": "INFO",
|
||||
}
|
||||
|
||||
|
||||
@ -60,12 +60,41 @@ def _init_bot(nonebug_init: None):
|
||||
|
||||
nonebot.load_plugin("nonebot_plugin_alconna")
|
||||
nonebot.load_plugin("nonebot_plugin_apscheduler")
|
||||
nonebot.load_plugin("nonebot_plugin_userinfo")
|
||||
nonebot.load_plugin("nonebot_plugin_htmlrender")
|
||||
|
||||
nonebot.load_plugins("zhenxun/builtin_plugins")
|
||||
nonebot.load_plugins("zhenxun/plugins")
|
||||
|
||||
# 手动缓存 uninfo 所需信息
|
||||
from nonebot_plugin_uninfo import (
|
||||
Scene,
|
||||
SceneType,
|
||||
Session,
|
||||
SupportAdapter,
|
||||
SupportScope,
|
||||
User,
|
||||
)
|
||||
from nonebot_plugin_uninfo.adapters.onebot11.main import fetcher as onebot11_fetcher
|
||||
from nonebot_plugin_uninfo.adapters.onebot12.main import fetcher as onebot12_fetcher
|
||||
|
||||
onebot11_fetcher.session_cache = {
|
||||
f"group_{GroupId.GROUP_ID_LEVEL_5}_{UserId.SUPERUSER}": Session(
|
||||
self_id="test",
|
||||
adapter=SupportAdapter.onebot11,
|
||||
scope=SupportScope.qq_client,
|
||||
scene=Scene(str(GroupId.GROUP_ID_LEVEL_0), SceneType.GROUP),
|
||||
user=User(str(UserId.SUPERUSER)),
|
||||
),
|
||||
}
|
||||
onebot12_fetcher.session_cache = {
|
||||
f"group_{GroupId.GROUP_ID_LEVEL_5}_{UserId.SUPERUSER}": Session(
|
||||
self_id="test",
|
||||
adapter=SupportAdapter.onebot12,
|
||||
scope=SupportScope.qq_client,
|
||||
scene=Scene(str(GroupId.GROUP_ID_LEVEL_0), SceneType.GROUP),
|
||||
user=User(str(UserId.SUPERUSER)),
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def app(app: App, tmp_path: Path, mocker: MockerFixture):
|
||||
|
||||
@ -33,5 +33,5 @@ __plugin_meta__ = PluginMetadata(
|
||||
检测b站
|
||||
bil_logout 12345<-(退出登录的b站uid,通过检测b站获取)
|
||||
""",
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
@ -20,5 +20,5 @@ __plugin_meta__ = PluginMetadata(
|
||||
extra=PluginExtraData(
|
||||
author="xuanerwa",
|
||||
version="0.7",
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
@ -13,5 +13,5 @@ __plugin_meta__ = PluginMetadata(
|
||||
extra=PluginExtraData(
|
||||
author="HibiKier",
|
||||
version="0.1",
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
@ -14,5 +14,5 @@ __plugin_meta__ = PluginMetadata(
|
||||
author="HibiKier",
|
||||
version="0.1",
|
||||
menu_type="一些工具",
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
101
tests/response/plugin_store/zhenxun_bot_plugins_commit.json
Normal file
101
tests/response/plugin_store/zhenxun_bot_plugins_commit.json
Normal file
@ -0,0 +1,101 @@
|
||||
{
|
||||
"sha": "b101fbc",
|
||||
"node_id": "C_kwDOMndPGNoAKGIxMDFmYmNlODg4NjA4ZTJiYmU1YjVmZDI3OWUxNDY1MTY4ODEyYzc",
|
||||
"commit": {
|
||||
"author": {
|
||||
"name": "xuaner",
|
||||
"email": "xuaner_wa@qq.com",
|
||||
"date": "2024-09-20T12:08:27Z"
|
||||
},
|
||||
"committer": {
|
||||
"name": "xuaner",
|
||||
"email": "xuaner_wa@qq.com",
|
||||
"date": "2024-09-20T12:08:27Z"
|
||||
},
|
||||
"message": "🐛修复B站订阅bug",
|
||||
"tree": {
|
||||
"sha": "0566306219a434f7122798647498faef692c1879",
|
||||
"url": "https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins/git/trees/0566306219a434f7122798647498faef692c1879"
|
||||
},
|
||||
"url": "https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins/git/commits/b101fbce888608e2bbe5b5fd279e1465168812c7",
|
||||
"comment_count": 0,
|
||||
"verification": {
|
||||
"verified": false,
|
||||
"reason": "unsigned",
|
||||
"signature": null,
|
||||
"payload": null,
|
||||
"verified_at": null
|
||||
}
|
||||
},
|
||||
"url": "https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins/commits/b101fbce888608e2bbe5b5fd279e1465168812c7",
|
||||
"html_url": "https://github.com/zhenxun-org/zhenxun_bot_plugins/commit/b101fbce888608e2bbe5b5fd279e1465168812c7",
|
||||
"comments_url": "https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins/commits/b101fbce888608e2bbe5b5fd279e1465168812c7/comments",
|
||||
"author": {
|
||||
"login": "xuanerwa",
|
||||
"id": 58063798,
|
||||
"node_id": "MDQ6VXNlcjU4MDYzNzk4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/58063798?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/xuanerwa",
|
||||
"html_url": "https://github.com/xuanerwa",
|
||||
"followers_url": "https://api.github.com/users/xuanerwa/followers",
|
||||
"following_url": "https://api.github.com/users/xuanerwa/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/xuanerwa/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/xuanerwa/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/xuanerwa/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/xuanerwa/orgs",
|
||||
"repos_url": "https://api.github.com/users/xuanerwa/repos",
|
||||
"events_url": "https://api.github.com/users/xuanerwa/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/xuanerwa/received_events",
|
||||
"type": "User",
|
||||
"user_view_type": "public",
|
||||
"site_admin": false
|
||||
},
|
||||
"committer": {
|
||||
"login": "xuanerwa",
|
||||
"id": 58063798,
|
||||
"node_id": "MDQ6VXNlcjU4MDYzNzk4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/58063798?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/xuanerwa",
|
||||
"html_url": "https://github.com/xuanerwa",
|
||||
"followers_url": "https://api.github.com/users/xuanerwa/followers",
|
||||
"following_url": "https://api.github.com/users/xuanerwa/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/xuanerwa/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/xuanerwa/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/xuanerwa/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/xuanerwa/orgs",
|
||||
"repos_url": "https://api.github.com/users/xuanerwa/repos",
|
||||
"events_url": "https://api.github.com/users/xuanerwa/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/xuanerwa/received_events",
|
||||
"type": "User",
|
||||
"user_view_type": "public",
|
||||
"site_admin": false
|
||||
},
|
||||
"parents": [
|
||||
{
|
||||
"sha": "a545dfa0c4e149595f7ddd50dc34c55513738fb9",
|
||||
"url": "https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins/commits/a545dfa0c4e149595f7ddd50dc34c55513738fb9",
|
||||
"html_url": "https://github.com/zhenxun-org/zhenxun_bot_plugins/commit/a545dfa0c4e149595f7ddd50dc34c55513738fb9"
|
||||
}
|
||||
],
|
||||
"stats": {
|
||||
"total": 4,
|
||||
"additions": 2,
|
||||
"deletions": 2
|
||||
},
|
||||
"files": [
|
||||
{
|
||||
"sha": "0fbc9695db04c56174e3bff933f670d8d2df2abc",
|
||||
"filename": "plugins/bilibili_sub/data_source.py",
|
||||
"status": "modified",
|
||||
"additions": 2,
|
||||
"deletions": 2,
|
||||
"changes": 4,
|
||||
"blob_url": "https://github.com/zhenxun-org/zhenxun_bot_plugins/blob/b101fbce888608e2bbe5b5fd279e1465168812c7/plugins%2Fbilibili_sub%2Fdata_source.py",
|
||||
"raw_url": "https://github.com/zhenxun-org/zhenxun_bot_plugins/raw/b101fbce888608e2bbe5b5fd279e1465168812c7/plugins%2Fbilibili_sub%2Fdata_source.py",
|
||||
"contents_url": "https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins/contents/plugins%2Fbilibili_sub%2Fdata_source.py?ref=b101fbce888608e2bbe5b5fd279e1465168812c7",
|
||||
"patch": "@@ -271,14 +271,14 @@ async def _get_live_status(id_: int) -> list:\n sub = await BilibiliSub.get_or_none(sub_id=id_)\n msg_list = []\n if sub.live_status != live_status:\n+ await BilibiliSub.sub_handle(id_, live_status=live_status)\n image = None\n try:\n image_bytes = await fetch_image_bytes(cover)\n image = BuildImage(background = image_bytes)\n except Exception as e:\n logger.error(f\"图片构造失败,错误信息:{e}\")\n if sub.live_status in [0, 2] and live_status == 1 and image:\n- await BilibiliSub.sub_handle(id_, live_status=live_status)\n msg_list = [\n image,\n \"\\n\",\n@@ -322,7 +322,7 @@ async def _get_up_status(id_: int) -> list:\n video = video_info[\"list\"][\"vlist\"][0]\n latest_video_created = video[\"created\"]\n msg_list = []\n- if dynamic_img:\n+ if dynamic_img and _user.dynamic_upload_time < dynamic_upload_time:\n await BilibiliSub.sub_handle(id_, dynamic_upload_time=dynamic_upload_time)\n msg_list = [f\"{uname} 发布了动态!📢\\n\", dynamic_img, f\"\\n查看详情:{link}\"]\n if ("
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,101 @@
|
||||
{
|
||||
"sha": "2ed61284873c526802752b12a3fd3b5e1a59d948",
|
||||
"node_id": "C_kwDOGK5Du9oAKDJlZDYxMjg0ODczYzUyNjgwMjc1MmIxMmEzZmQzYjVlMWE1OWQ5NDg",
|
||||
"commit": {
|
||||
"author": {
|
||||
"name": "zhenxunflow[bot]",
|
||||
"email": "179375394+zhenxunflow[bot]@users.noreply.github.com",
|
||||
"date": "2025-01-26T09:04:55Z"
|
||||
},
|
||||
"committer": {
|
||||
"name": "GitHub",
|
||||
"email": "noreply@github.com",
|
||||
"date": "2025-01-26T09:04:55Z"
|
||||
},
|
||||
"message": ":beers: publish plugin AI全家桶 (#235) (#236)\n\nCo-authored-by: molanp <molanp@users.noreply.github.com>",
|
||||
"tree": {
|
||||
"sha": "64ea463e084b6ab0def0322c6ad53799054ec9b3",
|
||||
"url": "https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins_index/git/trees/64ea463e084b6ab0def0322c6ad53799054ec9b3"
|
||||
},
|
||||
"url": "https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins_index/git/commits/2ed61284873c526802752b12a3fd3b5e1a59d948",
|
||||
"comment_count": 0,
|
||||
"verification": {
|
||||
"verified": true,
|
||||
"reason": "valid",
|
||||
"signature": "-----BEGIN PGP SIGNATURE-----\n\nwsFcBAABCAAQBQJnlfq3CRC1aQ7uu5UhlAAA+n0QADPVjQQIHFlNcTEgdq3LGQ1X\nm8+H5N07E5JD+83LdyU9/YOvqY/WURwFsQ0T4+23icUWEOD4LB5qZIdVJBYHseto\nbJNmYd1kZxpvsONoiK/2Uk6JoeVnEQIR+dTbB0wBlbL0lRt1WtTXHpLQbFXuXn3q\nJh4SdSj283UZ6D2sBADblPZ7DqaTmLlpgwrTPx0OH5wIhcuORkzOl6x0DabcVAYu\nu5zHSKM9c7g+jEmrqRuVy+ZlZMDPN4S3gDNzEhoTn4tn+KNzSIja4n7ZMRD+1a5X\nMIP3aXcVBqCyuYc6DU76IvjlaL/MjnlPwfOtx1zu+pNxZKNaSpojtqopp3blfk0E\n8s8lD9utDgUaUrdPWgpiMDjj+oNMye91CGomNDfv0fNGUlBGT6r48qaq1z8BwAAR\nzgDsF13kDuKTTkT/6T8CdgCpJtwvxMptUr2XFRtn4xwf/gJdqrbEc4fHTOSHqxzh\ncDfXuP+Sorla4oJ0duygTsulpr/zguX8RJWJml35VjERw54ARAVvhZn19G9qQVJo\n2QIp+xtyTjkM3yTeN4UDXFt4lDuxz3+l1MBduj+CHn+WTgxyJUpX2TA1GVfni9xT\npOMOtzuDQfDIxTNB6hFjSWATb1/E5ys1lfK09n+dRhmvC/Be+b5M4WlyX3cqy/za\ns0XxuZ+CHzLfHaPxFUem\n=VYpl\n-----END PGP SIGNATURE-----\n",
|
||||
"payload": "tree 64ea463e084b6ab0def0322c6ad53799054ec9b3\nparent 5df26081d40e3000a7beedb73954d4df397c93fa\nauthor zhenxunflow[bot] <179375394+zhenxunflow[bot]@users.noreply.github.com> 1737882295 +0800\ncommitter GitHub <noreply@github.com> 1737882295 +0800\n\n:beers: publish plugin AI全家桶 (#235) (#236)\n\nCo-authored-by: molanp <molanp@users.noreply.github.com>",
|
||||
"verified_at": "2025-01-26T09:04:58Z"
|
||||
}
|
||||
},
|
||||
"url": "https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins_index/commits/2ed61284873c526802752b12a3fd3b5e1a59d948",
|
||||
"html_url": "https://github.com/zhenxun-org/zhenxun_bot_plugins_index/commit/2ed61284873c526802752b12a3fd3b5e1a59d948",
|
||||
"comments_url": "https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins_index/commits/2ed61284873c526802752b12a3fd3b5e1a59d948/comments",
|
||||
"author": {
|
||||
"login": "zhenxunflow[bot]",
|
||||
"id": 179375394,
|
||||
"node_id": "BOT_kgDOCrENIg",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/in/978723?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/zhenxunflow%5Bbot%5D",
|
||||
"html_url": "https://github.com/apps/zhenxunflow",
|
||||
"followers_url": "https://api.github.com/users/zhenxunflow%5Bbot%5D/followers",
|
||||
"following_url": "https://api.github.com/users/zhenxunflow%5Bbot%5D/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/zhenxunflow%5Bbot%5D/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/zhenxunflow%5Bbot%5D/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/zhenxunflow%5Bbot%5D/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/zhenxunflow%5Bbot%5D/orgs",
|
||||
"repos_url": "https://api.github.com/users/zhenxunflow%5Bbot%5D/repos",
|
||||
"events_url": "https://api.github.com/users/zhenxunflow%5Bbot%5D/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/zhenxunflow%5Bbot%5D/received_events",
|
||||
"type": "Bot",
|
||||
"user_view_type": "public",
|
||||
"site_admin": false
|
||||
},
|
||||
"committer": {
|
||||
"login": "web-flow",
|
||||
"id": 19864447,
|
||||
"node_id": "MDQ6VXNlcjE5ODY0NDQ3",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/web-flow",
|
||||
"html_url": "https://github.com/web-flow",
|
||||
"followers_url": "https://api.github.com/users/web-flow/followers",
|
||||
"following_url": "https://api.github.com/users/web-flow/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/web-flow/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/web-flow/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/web-flow/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/web-flow/orgs",
|
||||
"repos_url": "https://api.github.com/users/web-flow/repos",
|
||||
"events_url": "https://api.github.com/users/web-flow/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/web-flow/received_events",
|
||||
"type": "User",
|
||||
"user_view_type": "public",
|
||||
"site_admin": false
|
||||
},
|
||||
"parents": [
|
||||
{
|
||||
"sha": "5df26081d40e3000a7beedb73954d4df397c93fa",
|
||||
"url": "https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins_index/commits/5df26081d40e3000a7beedb73954d4df397c93fa",
|
||||
"html_url": "https://github.com/zhenxun-org/zhenxun_bot_plugins_index/commit/5df26081d40e3000a7beedb73954d4df397c93fa"
|
||||
}
|
||||
],
|
||||
"stats": {
|
||||
"total": 11,
|
||||
"additions": 11,
|
||||
"deletions": 0
|
||||
},
|
||||
"files": [
|
||||
{
|
||||
"sha": "3d98392c25d38f5d375b830aed6e2298e47e5601",
|
||||
"filename": "plugins.json",
|
||||
"status": "modified",
|
||||
"additions": 11,
|
||||
"deletions": 0,
|
||||
"changes": 11,
|
||||
"blob_url": "https://github.com/zhenxun-org/zhenxun_bot_plugins_index/blob/2ed61284873c526802752b12a3fd3b5e1a59d948/plugins.json",
|
||||
"raw_url": "https://github.com/zhenxun-org/zhenxun_bot_plugins_index/raw/2ed61284873c526802752b12a3fd3b5e1a59d948/plugins.json",
|
||||
"contents_url": "https://api.github.com/repos/zhenxun-org/zhenxun_bot_plugins_index/contents/plugins.json?ref=2ed61284873c526802752b12a3fd3b5e1a59d948",
|
||||
"patch": "@@ -53,5 +53,16 @@\n \"plugin_type\": \"NORMAL\",\n \"is_dir\": true,\n \"github_url\": \"https://github.com/PackageInstaller/zhenxun_plugin_draw_painting/tree/master\"\n+ },\n+ \"AI全家桶\": {\n+ \"module\": \"zhipu_toolkit\",\n+ \"module_path\": \"zhipu_toolkit\",\n+ \"description\": \"AI全家桶,一次安装,到处使用,省时省力省心\",\n+ \"usage\": \"AI全家桶,一次安装,到处使用,省时省力省心\\n usage:\\n 生成图片 <prompt>\\n 生成视频 <prompt>\\n 清理我的会话: 用于清理你与AI的聊天记录\\n 或者与机器人聊天,\\n 例如;\\n @Bot抱抱\\n 小真寻老婆\",\n+ \"author\": \"molanp\",\n+ \"version\": \"0.1\",\n+ \"plugin_type\": \"NORMAL\",\n+ \"is_dir\": true,\n+ \"github_url\": \"https://github.com/molanp/zhenxun_plugin_zhipu_toolkit\"\n }\n }"
|
||||
}
|
||||
]
|
||||
}
|
||||
101
tests/response/plugin_store/zhenxun_github_sub_commit.json
Normal file
101
tests/response/plugin_store/zhenxun_github_sub_commit.json
Normal file
@ -0,0 +1,101 @@
|
||||
{
|
||||
"sha": "f524632f78d27f9893beebdf709e0e7885cd08f1",
|
||||
"node_id": "C_kwDOJAjBPdoAKGY1MjQ2MzJmNzhkMjdmOTg5M2JlZWJkZjcwOWUwZTc4ODVjZDA4ZjE",
|
||||
"commit": {
|
||||
"author": {
|
||||
"name": "xuaner",
|
||||
"email": "xuaner_wa@qq.com",
|
||||
"date": "2024-11-18T18:17:15Z"
|
||||
},
|
||||
"committer": {
|
||||
"name": "xuaner",
|
||||
"email": "xuaner_wa@qq.com",
|
||||
"date": "2024-11-18T18:17:15Z"
|
||||
},
|
||||
"message": "fix bug",
|
||||
"tree": {
|
||||
"sha": "b6b1b4f06cc869b9f38d7b51bdca3a2c575255e4",
|
||||
"url": "https://api.github.com/repos/xuanerwa/zhenxun_github_sub/git/trees/b6b1b4f06cc869b9f38d7b51bdca3a2c575255e4"
|
||||
},
|
||||
"url": "https://api.github.com/repos/xuanerwa/zhenxun_github_sub/git/commits/f524632f78d27f9893beebdf709e0e7885cd08f1",
|
||||
"comment_count": 0,
|
||||
"verification": {
|
||||
"verified": false,
|
||||
"reason": "unsigned",
|
||||
"signature": null,
|
||||
"payload": null,
|
||||
"verified_at": null
|
||||
}
|
||||
},
|
||||
"url": "https://api.github.com/repos/xuanerwa/zhenxun_github_sub/commits/f524632f78d27f9893beebdf709e0e7885cd08f1",
|
||||
"html_url": "https://github.com/xuanerwa/zhenxun_github_sub/commit/f524632f78d27f9893beebdf709e0e7885cd08f1",
|
||||
"comments_url": "https://api.github.com/repos/xuanerwa/zhenxun_github_sub/commits/f524632f78d27f9893beebdf709e0e7885cd08f1/comments",
|
||||
"author": {
|
||||
"login": "xuanerwa",
|
||||
"id": 58063798,
|
||||
"node_id": "MDQ6VXNlcjU4MDYzNzk4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/58063798?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/xuanerwa",
|
||||
"html_url": "https://github.com/xuanerwa",
|
||||
"followers_url": "https://api.github.com/users/xuanerwa/followers",
|
||||
"following_url": "https://api.github.com/users/xuanerwa/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/xuanerwa/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/xuanerwa/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/xuanerwa/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/xuanerwa/orgs",
|
||||
"repos_url": "https://api.github.com/users/xuanerwa/repos",
|
||||
"events_url": "https://api.github.com/users/xuanerwa/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/xuanerwa/received_events",
|
||||
"type": "User",
|
||||
"user_view_type": "public",
|
||||
"site_admin": false
|
||||
},
|
||||
"committer": {
|
||||
"login": "xuanerwa",
|
||||
"id": 58063798,
|
||||
"node_id": "MDQ6VXNlcjU4MDYzNzk4",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/58063798?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/xuanerwa",
|
||||
"html_url": "https://github.com/xuanerwa",
|
||||
"followers_url": "https://api.github.com/users/xuanerwa/followers",
|
||||
"following_url": "https://api.github.com/users/xuanerwa/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/xuanerwa/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/xuanerwa/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/xuanerwa/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/xuanerwa/orgs",
|
||||
"repos_url": "https://api.github.com/users/xuanerwa/repos",
|
||||
"events_url": "https://api.github.com/users/xuanerwa/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/xuanerwa/received_events",
|
||||
"type": "User",
|
||||
"user_view_type": "public",
|
||||
"site_admin": false
|
||||
},
|
||||
"parents": [
|
||||
{
|
||||
"sha": "91e5e2c792e79193830441d555769aa54acd2d15",
|
||||
"url": "https://api.github.com/repos/xuanerwa/zhenxun_github_sub/commits/91e5e2c792e79193830441d555769aa54acd2d15",
|
||||
"html_url": "https://github.com/xuanerwa/zhenxun_github_sub/commit/91e5e2c792e79193830441d555769aa54acd2d15"
|
||||
}
|
||||
],
|
||||
"stats": {
|
||||
"total": 2,
|
||||
"additions": 1,
|
||||
"deletions": 1
|
||||
},
|
||||
"files": [
|
||||
{
|
||||
"sha": "764a5f7b81554c4c10d29486ea5d9105e505cec3",
|
||||
"filename": "github_sub/__init__.py",
|
||||
"status": "modified",
|
||||
"additions": 1,
|
||||
"deletions": 1,
|
||||
"changes": 2,
|
||||
"blob_url": "https://github.com/xuanerwa/zhenxun_github_sub/blob/f524632f78d27f9893beebdf709e0e7885cd08f1/github_sub%2F__init__.py",
|
||||
"raw_url": "https://github.com/xuanerwa/zhenxun_github_sub/raw/f524632f78d27f9893beebdf709e0e7885cd08f1/github_sub%2F__init__.py",
|
||||
"contents_url": "https://api.github.com/repos/xuanerwa/zhenxun_github_sub/contents/github_sub%2F__init__.py?ref=f524632f78d27f9893beebdf709e0e7885cd08f1",
|
||||
"patch": "@@ -168,7 +168,7 @@ async def _(session: EventSession):\n # 推送\n @scheduler.scheduled_job(\n \"interval\",\n- seconds=base_config.get(\"CHECK_API_TIME\") if base_config.get(\"CHECK_TIME\") else 30,\n+ seconds=base_config.get(\"CHECK_API_TIME\") if base_config.get(\"CHECK_API_TIME\") else 30,\n )\n async def _():\n bots = nonebot.get_bots()"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -19,7 +19,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
指令:
|
||||
关于
|
||||
""".strip(),
|
||||
extra=PluginExtraData(author="HibiKier", version="0.1", menu_type="其他").dict(),
|
||||
extra=PluginExtraData(author="HibiKier", version="0.1", menu_type="其他").to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
default_value="zhenxun",
|
||||
)
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
_matcher = on_alconna(
|
||||
|
||||
@ -15,7 +15,8 @@ async def get_task() -> dict[str, str] | None:
|
||||
return {
|
||||
"name": "被动技能",
|
||||
"description": "控制群组中的被动技能状态",
|
||||
"usage": "通过 开启/关闭群被动 来控制群被<br>----------<br>"
|
||||
"usage": "通过 开启/关闭群被动 来控制群被动 <br>"
|
||||
+ " 示例:开启/关闭群被动早晚安 <br> ---------- <br> "
|
||||
+ "<br>".join([task.name for task in task_list]),
|
||||
}
|
||||
return None
|
||||
|
||||
@ -27,7 +27,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
default_value=5,
|
||||
)
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
type=int,
|
||||
)
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -105,7 +105,7 @@ class BanManage:
|
||||
if idx:
|
||||
ban_data = await BanConsole.get_or_none(id=idx)
|
||||
if not ban_data:
|
||||
return False, "该用户/群组不在黑名单中不足捏..."
|
||||
return False, "该用户/群组不在黑名单中捏..."
|
||||
if ban_data.ban_level > user_level:
|
||||
return False, "unBan权限等级不足捏..."
|
||||
await ban_data.delete()
|
||||
|
||||
@ -30,7 +30,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
version="0.1",
|
||||
plugin_type=PluginType.SUPER_AND_ADMIN,
|
||||
admin_level=1,
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
version="0.1",
|
||||
plugin_type=PluginType.SUPER_AND_ADMIN,
|
||||
admin_level=1,
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -80,7 +80,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
type=int,
|
||||
)
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import os
|
||||
|
||||
from zhenxun.configs.path_config import DATA_PATH, IMAGE_PATH
|
||||
from zhenxun.models.group_console import GroupConsole
|
||||
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):
|
||||
"""删除帮助图片"""
|
||||
if gid:
|
||||
file = GROUP_HELP_PATH / f"{gid}.png"
|
||||
if file.exists():
|
||||
file.unlink()
|
||||
for file in os.listdir(GROUP_HELP_PATH):
|
||||
if file.startswith(f"{gid}"):
|
||||
os.remove(GROUP_HELP_PATH / file)
|
||||
else:
|
||||
if HELP_FILE.exists():
|
||||
HELP_FILE.unlink()
|
||||
|
||||
@ -57,7 +57,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
default_value=2,
|
||||
)
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
_matcher = on_command(
|
||||
@ -125,7 +125,7 @@ async def _(session: Uninfo, arparma: Arparma, idx: Match[int]):
|
||||
|
||||
@_del_matcher.handle()
|
||||
async def _(session: Uninfo, arparma: Arparma, idx: int):
|
||||
result = await Manager.delete_group_message(session, int(idx))
|
||||
result = await Manager.delete_group_message(session, idx)
|
||||
if not result:
|
||||
await MessageUtils.build_message("未查找到指定id的群组欢迎消息...").finish()
|
||||
await MessageUtils.build_message(result).send()
|
||||
|
||||
@ -22,8 +22,11 @@ BASE_PATH.mkdir(parents=True, exist_ok=True)
|
||||
driver = nonebot.get_driver()
|
||||
|
||||
|
||||
old_file = DATA_PATH / "custom_welcome_msg" / "custom_welcome_msg.json"
|
||||
if old_file.exists():
|
||||
def __migrate():
|
||||
"""首次数据迁移"""
|
||||
old_file = DATA_PATH / "custom_welcome_msg" / "custom_welcome_msg.json"
|
||||
if not old_file.exists():
|
||||
return
|
||||
try:
|
||||
old_data: dict[str, str] = json.load(old_file.open(encoding="utf8"))
|
||||
for group_id, message in old_data.items():
|
||||
@ -53,7 +56,10 @@ def migrate(path: Path):
|
||||
参数:
|
||||
path: 路径
|
||||
"""
|
||||
__migrate()
|
||||
text_file = path / "text.json"
|
||||
if not text_file.exists():
|
||||
return
|
||||
with text_file.open(encoding="utf8") as f:
|
||||
json_data = json.load(f)
|
||||
new_data = {}
|
||||
@ -206,6 +212,8 @@ class Manager:
|
||||
返回:
|
||||
list: 消息内容
|
||||
"""
|
||||
if not session.group:
|
||||
return None
|
||||
json_data = cls.__get_data(session)
|
||||
if not json_data:
|
||||
return None
|
||||
@ -244,9 +252,11 @@ class Manager:
|
||||
返回:
|
||||
list: 消息内容
|
||||
"""
|
||||
path = cls.get_path(session)
|
||||
json_data = cls.__get_data(session)
|
||||
if not json_data:
|
||||
if not json_data or not path:
|
||||
return None
|
||||
file = path / "text.json"
|
||||
key_list = list(json_data.keys())
|
||||
if idx < 0 or idx >= len(key_list):
|
||||
return None
|
||||
|
||||
@ -47,7 +47,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
author="HibiKier",
|
||||
version="0.1",
|
||||
plugin_type=PluginType.SUPERUSER,
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
_matcher = on_alconna(
|
||||
|
||||
@ -29,7 +29,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
type=bool,
|
||||
)
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
@ -39,7 +39,6 @@ def rule(message: UniMsg) -> bool:
|
||||
|
||||
chat_history = on_message(rule=rule, priority=1, block=False)
|
||||
|
||||
|
||||
TEMP_LIST = []
|
||||
|
||||
|
||||
@ -70,14 +69,4 @@ async def _():
|
||||
await ChatHistory.bulk_create(message_list)
|
||||
logger.debug(f"批量添加聊天记录 {len(message_list)} 条", "定时任务")
|
||||
except Exception as e:
|
||||
logger.error("定时批量添加聊天记录", "定时任务", 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))
|
||||
logger.warning("存储聊天记录失败", "chat_history", e=e)
|
||||
|
||||
@ -14,7 +14,7 @@ from nonebot_plugin_alconna import (
|
||||
from nonebot_plugin_session import EventSession
|
||||
import pytz
|
||||
|
||||
from zhenxun.configs.utils import PluginExtraData
|
||||
from zhenxun.configs.utils import Command, PluginExtraData
|
||||
from zhenxun.models.chat_history import ChatHistory
|
||||
from zhenxun.models.group_member_info import GroupInfoUser
|
||||
from zhenxun.services.log import logger
|
||||
@ -45,7 +45,14 @@ __plugin_meta__ = PluginMetadata(
|
||||
version="0.1",
|
||||
plugin_type=PluginType.NORMAL,
|
||||
menu_type="数据统计",
|
||||
).dict(),
|
||||
commands=[
|
||||
Command(command="消息统计"),
|
||||
Command(command="日消息统计"),
|
||||
Command(command="周消息排行"),
|
||||
Command(command="月消息排行"),
|
||||
Command(command="年消息排行"),
|
||||
],
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
default_value="mix",
|
||||
)
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ ARM_KEY = "aarch64"
|
||||
|
||||
@dataclass
|
||||
class CPUInfo:
|
||||
core: int
|
||||
core: int | None
|
||||
"""CPU 物理核心数"""
|
||||
usage: float
|
||||
"""CPU 占用百分比,取值范围(0,100]"""
|
||||
|
||||
@ -13,7 +13,11 @@ from nonebot_plugin_alconna import (
|
||||
)
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
|
||||
from zhenxun.builtin_plugins.help._config import GROUP_HELP_PATH, SIMPLE_HELP_IMAGE
|
||||
from zhenxun.builtin_plugins.help._config import (
|
||||
GROUP_HELP_PATH,
|
||||
SIMPLE_DETAIL_HELP_IMAGE,
|
||||
SIMPLE_HELP_IMAGE,
|
||||
)
|
||||
from zhenxun.configs.utils import PluginExtraData, RegisterConfig
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.utils.enum import PluginType
|
||||
@ -38,7 +42,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
default_value="zhenxun",
|
||||
)
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
@ -47,6 +51,7 @@ _matcher = on_alconna(
|
||||
"功能",
|
||||
Args["name?", str],
|
||||
Option("-s|--superuser", action=store_true, help_text="超级用户帮助"),
|
||||
Option("-d|--detail", action=store_true, help_text="详细帮助"),
|
||||
),
|
||||
aliases={"help", "帮助", "菜单"},
|
||||
rule=to_me(),
|
||||
@ -55,12 +60,21 @@ _matcher = on_alconna(
|
||||
)
|
||||
|
||||
|
||||
_matcher.shortcut(
|
||||
r"详细帮助",
|
||||
command="功能",
|
||||
arguments=["--detail"],
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
|
||||
@_matcher.handle()
|
||||
async def _(
|
||||
bot: Bot,
|
||||
name: Match[str],
|
||||
session: Uninfo,
|
||||
is_superuser: Query[bool] = AlconnaQuery("superuser.value", False),
|
||||
is_detail: Query[bool] = AlconnaQuery("detail.value", False),
|
||||
):
|
||||
_is_superuser = is_superuser.result if is_superuser.available else False
|
||||
if name.available:
|
||||
@ -74,11 +88,15 @@ async def _(
|
||||
)
|
||||
logger.info(f"查看帮助详情: {name.result}", "帮助", session=session)
|
||||
elif session.group and (gid := session.group.id):
|
||||
_image_path = GROUP_HELP_PATH / f"{gid}.png"
|
||||
_image_path = GROUP_HELP_PATH / f"{gid}_{is_detail.result}.png"
|
||||
if not _image_path.exists():
|
||||
await create_help_img(session, gid)
|
||||
result = await create_help_img(session, gid, is_detail.result)
|
||||
await MessageUtils.build_message(_image_path).finish()
|
||||
else:
|
||||
if not SIMPLE_HELP_IMAGE.exists():
|
||||
await create_help_img(session, None)
|
||||
await MessageUtils.build_message(SIMPLE_HELP_IMAGE).finish()
|
||||
if is_detail.result:
|
||||
_image_path = SIMPLE_DETAIL_HELP_IMAGE
|
||||
else:
|
||||
_image_path = SIMPLE_HELP_IMAGE
|
||||
if not _image_path.exists():
|
||||
result = await create_help_img(session, None, is_detail.result)
|
||||
await MessageUtils.build_message(_image_path).finish()
|
||||
|
||||
@ -10,4 +10,8 @@ SIMPLE_HELP_IMAGE = IMAGE_PATH / "SIMPLE_HELP.png"
|
||||
if SIMPLE_HELP_IMAGE.exists():
|
||||
SIMPLE_HELP_IMAGE.unlink()
|
||||
|
||||
SIMPLE_DETAIL_HELP_IMAGE = IMAGE_PATH / "SIMPLE_DETAIL_HELP.png"
|
||||
if SIMPLE_DETAIL_HELP_IMAGE.exists():
|
||||
SIMPLE_DETAIL_HELP_IMAGE.unlink()
|
||||
|
||||
base_config = Config.get("help")
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
from pathlib import Path
|
||||
|
||||
import nonebot
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
|
||||
@ -7,7 +9,12 @@ from zhenxun.models.plugin_info import PluginInfo
|
||||
from zhenxun.utils.enum import PluginType
|
||||
from zhenxun.utils.image_utils import BuildImage, ImageTemplate
|
||||
|
||||
from ._config import GROUP_HELP_PATH, SIMPLE_HELP_IMAGE, base_config
|
||||
from ._config import (
|
||||
GROUP_HELP_PATH,
|
||||
SIMPLE_DETAIL_HELP_IMAGE,
|
||||
SIMPLE_HELP_IMAGE,
|
||||
base_config,
|
||||
)
|
||||
from .html_help import build_html_image
|
||||
from .normal_help import build_normal_image
|
||||
from .zhenxun_help import build_zhenxun_image
|
||||
@ -20,7 +27,9 @@ background = IMAGE_PATH / "background" / "0.png"
|
||||
driver = nonebot.get_driver()
|
||||
|
||||
|
||||
async def create_help_img(session: Uninfo, group_id: str | None):
|
||||
async def create_help_img(
|
||||
session: Uninfo, group_id: str | None, is_detail: bool
|
||||
) -> Path:
|
||||
"""生成帮助图片
|
||||
|
||||
参数:
|
||||
@ -31,14 +40,21 @@ async def create_help_img(session: Uninfo, group_id: str | None):
|
||||
|
||||
match help_type:
|
||||
case "html":
|
||||
result = BuildImage.open(await build_html_image(group_id))
|
||||
result = BuildImage.open(await build_html_image(group_id, is_detail))
|
||||
case "zhenxun":
|
||||
result = BuildImage.open(await build_zhenxun_image(session, group_id))
|
||||
result = BuildImage.open(
|
||||
await build_zhenxun_image(session, group_id, is_detail)
|
||||
)
|
||||
case _:
|
||||
result = await build_normal_image(group_id)
|
||||
|
||||
save_path = GROUP_HELP_PATH / f"{group_id}.png" if group_id else SIMPLE_HELP_IMAGE
|
||||
result = await build_normal_image(group_id, is_detail)
|
||||
if group_id:
|
||||
save_path = GROUP_HELP_PATH / f"{group_id}_{is_detail}.png"
|
||||
elif is_detail:
|
||||
save_path = SIMPLE_DETAIL_HELP_IMAGE
|
||||
else:
|
||||
save_path = SIMPLE_HELP_IMAGE
|
||||
await result.save(save_path)
|
||||
return save_path
|
||||
|
||||
|
||||
async def get_user_allow_help(user_id: str) -> list[PluginType]:
|
||||
|
||||
@ -26,11 +26,14 @@ async def sort_type() -> dict[str, list[PluginInfo]]:
|
||||
return sort_data
|
||||
|
||||
|
||||
async def classify_plugin(group_id: str | None, handle: Callable) -> dict[str, list]:
|
||||
async def classify_plugin(
|
||||
group_id: str | None, is_detail: bool, handle: Callable
|
||||
) -> dict[str, list]:
|
||||
"""对插件进行分类并判断状态
|
||||
|
||||
参数:
|
||||
group_id: 群组id
|
||||
is_detail: 是否详细帮助
|
||||
|
||||
返回:
|
||||
dict[str, list[Item]]: 分类插件数据
|
||||
@ -42,5 +45,5 @@ async def classify_plugin(group_id: str | None, handle: Callable) -> dict[str, l
|
||||
for plugin in value:
|
||||
if not classify.get(menu):
|
||||
classify[menu] = []
|
||||
classify[menu].append(handle(plugin, group))
|
||||
classify[menu].append(handle(plugin, group, is_detail))
|
||||
return classify
|
||||
|
||||
@ -47,12 +47,15 @@ ICON2STR = {
|
||||
}
|
||||
|
||||
|
||||
def __handle_item(plugin: PluginInfo, group: GroupConsole | None) -> Item:
|
||||
def __handle_item(
|
||||
plugin: PluginInfo, group: GroupConsole | None, is_detail: bool
|
||||
) -> Item:
|
||||
"""构造Item
|
||||
|
||||
参数:
|
||||
plugin: PluginInfo
|
||||
group: 群组
|
||||
is_detail: 是否详细
|
||||
|
||||
返回:
|
||||
Item: Item
|
||||
@ -116,13 +119,14 @@ def build_plugin_data(classify: dict[str, list[Item]]) -> list[dict[str, str]]:
|
||||
return plugin_list
|
||||
|
||||
|
||||
async def build_html_image(group_id: str | None) -> bytes:
|
||||
async def build_html_image(group_id: str | None, is_detail: bool) -> bytes:
|
||||
"""构造HTML帮助图片
|
||||
|
||||
参数:
|
||||
group_id: 群号
|
||||
is_detail: 是否详细帮助
|
||||
"""
|
||||
classify = await classify_plugin(group_id, __handle_item)
|
||||
classify = await classify_plugin(group_id, is_detail, __handle_item)
|
||||
plugin_list = build_plugin_data(classify)
|
||||
return await template_to_pic(
|
||||
template_path=str((TEMPLATE_PATH / "menu").absolute()),
|
||||
|
||||
@ -9,11 +9,12 @@ from ._utils import sort_type
|
||||
BACKGROUND_PATH = IMAGE_PATH / "background" / "help" / "simple_help"
|
||||
|
||||
|
||||
async def build_normal_image(group_id: str | None) -> BuildImage:
|
||||
async def build_normal_image(group_id: str | None, is_detail: bool) -> BuildImage:
|
||||
"""构造PIL帮助图片
|
||||
|
||||
参数:
|
||||
group_id: 群号
|
||||
is_detail: 详细帮助
|
||||
"""
|
||||
image_list = []
|
||||
font_size = 24
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import nonebot
|
||||
from nonebot_plugin_htmlrender import template_to_pic
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from pydantic import BaseModel
|
||||
|
||||
from zhenxun.configs.config import BotConfig
|
||||
from zhenxun.configs.path_config import TEMPLATE_PATH
|
||||
from zhenxun.configs.utils import PluginExtraData
|
||||
from zhenxun.models.group_console import GroupConsole
|
||||
from zhenxun.models.plugin_info import PluginInfo
|
||||
from zhenxun.utils.enum import BlockType
|
||||
@ -15,9 +17,11 @@ from ._utils import classify_plugin
|
||||
class Item(BaseModel):
|
||||
plugin_name: str
|
||||
"""插件名称"""
|
||||
commands: list[str]
|
||||
"""插件命令"""
|
||||
|
||||
|
||||
def __handle_item(plugin: PluginInfo, group: GroupConsole | None):
|
||||
def __handle_item(plugin: PluginInfo, group: GroupConsole | None, is_detail: bool):
|
||||
"""构造Item
|
||||
|
||||
参数:
|
||||
@ -36,7 +40,12 @@ def __handle_item(plugin: PluginInfo, group: GroupConsole | None):
|
||||
plugin.name = f"{plugin.name}(不可用)"
|
||||
elif group and f"{plugin.module}," in group.block_plugin:
|
||||
plugin.name = f"{plugin.name}(不可用)"
|
||||
return Item(plugin_name=f"{plugin.id}-{plugin.name}")
|
||||
commands = []
|
||||
nb_plugin = nonebot.get_plugin_by_module_name(plugin.module_path)
|
||||
if is_detail and nb_plugin and nb_plugin.metadata and nb_plugin.metadata.extra:
|
||||
extra_data = PluginExtraData(**nb_plugin.metadata.extra)
|
||||
commands = [cmd.command for cmd in extra_data.commands]
|
||||
return Item(plugin_name=f"{plugin.id}-{plugin.name}", commands=commands)
|
||||
|
||||
|
||||
def build_plugin_data(classify: dict[str, list[Item]]) -> list[dict[str, str]]:
|
||||
@ -123,18 +132,24 @@ def build_line_data(plugin_list: list[dict]) -> list[dict]:
|
||||
return data
|
||||
|
||||
|
||||
async def build_zhenxun_image(session: Uninfo, group_id: str | None) -> bytes:
|
||||
async def build_zhenxun_image(
|
||||
session: Uninfo, group_id: str | None, is_detail: bool
|
||||
) -> bytes:
|
||||
"""构造真寻帮助图片
|
||||
|
||||
参数:
|
||||
bot_id: bot_id
|
||||
group_id: 群号
|
||||
is_detail: 是否详细帮助
|
||||
"""
|
||||
classify = await classify_plugin(group_id, __handle_item)
|
||||
classify = await classify_plugin(group_id, is_detail, __handle_item)
|
||||
plugin_list = build_plugin_data(classify)
|
||||
platform = PlatformUtils.get_platform(session)
|
||||
bot_id = BotConfig.get_qbot_uid(session.self_id) or session.self_id
|
||||
bot_ava = PlatformUtils.get_user_avatar_url(bot_id, platform)
|
||||
width = int(637 * 1.5) if is_detail else 637
|
||||
title_font = int(53 * 1.5) if is_detail else 53
|
||||
tip_font = int(19 * 1.5) if is_detail else 19
|
||||
return await template_to_pic(
|
||||
template_path=str((TEMPLATE_PATH / "ss_menu").absolute()),
|
||||
template_name="main.html",
|
||||
@ -142,10 +157,13 @@ async def build_zhenxun_image(session: Uninfo, group_id: str | None) -> bytes:
|
||||
"data": {
|
||||
"plugin_list": plugin_list,
|
||||
"ava": bot_ava,
|
||||
"width": width,
|
||||
"font_size": (title_font, tip_font),
|
||||
"is_detail": is_detail,
|
||||
}
|
||||
},
|
||||
pages={
|
||||
"viewport": {"width": 637, "height": 453},
|
||||
"viewport": {"width": width, "height": 453},
|
||||
"base_url": f"file://{TEMPLATE_PATH}",
|
||||
},
|
||||
wait=2,
|
||||
|
||||
@ -2,11 +2,12 @@ import os
|
||||
import random
|
||||
|
||||
from nonebot import on_message
|
||||
from nonebot.adapters import Event
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot.rule import to_me
|
||||
from nonebot_plugin_alconna import UniMsg
|
||||
from nonebot_plugin_session import EventSession
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
|
||||
from zhenxun.configs.path_config import IMAGE_PATH
|
||||
from zhenxun.configs.utils import PluginExtraData
|
||||
@ -26,10 +27,25 @@ __plugin_meta__ = PluginMetadata(
|
||||
version="0.1",
|
||||
plugin_type=PluginType.DEPENDANT,
|
||||
menu_type="其他",
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
_matcher = on_message(rule=to_me(), priority=996, block=False)
|
||||
|
||||
async def rule(event: Event, message: UniMsg, session: Uninfo) -> bool:
|
||||
group_id = session.group.id if session.group else None
|
||||
text = message.extract_plain_text().strip()
|
||||
if await BanConsole.is_ban(session.user.id, group_id):
|
||||
return False
|
||||
if group_id:
|
||||
if await BanConsole.is_ban(None, group_id):
|
||||
return False
|
||||
if g := await GroupConsole.get_group(group_id):
|
||||
if g.level < 0:
|
||||
return False
|
||||
return event.is_tome() and bool(text and len(text) < 20)
|
||||
|
||||
|
||||
_matcher = on_message(rule=rule, priority=996, block=False)
|
||||
|
||||
|
||||
_path = IMAGE_PATH / "_base" / "laugh"
|
||||
@ -37,33 +53,30 @@ _path = IMAGE_PATH / "_base" / "laugh"
|
||||
|
||||
@_matcher.handle()
|
||||
async def _(matcher: Matcher, message: UniMsg, session: EventSession):
|
||||
gid = session.id3 or session.id2
|
||||
if await BanConsole.is_ban(session.id1, gid):
|
||||
text = message.extract_plain_text().strip()
|
||||
plugin = await PluginInfo.get_or_none(
|
||||
name=text,
|
||||
load_status=True,
|
||||
plugin_type=PluginType.NORMAL,
|
||||
block_type__isnull=True,
|
||||
status=True,
|
||||
)
|
||||
|
||||
if not plugin:
|
||||
return
|
||||
if gid:
|
||||
if await BanConsole.is_ban(None, gid):
|
||||
return
|
||||
if g := await GroupConsole.get_group(gid):
|
||||
if g.level < 0:
|
||||
return
|
||||
if text := message.extract_plain_text().strip():
|
||||
if plugin := await PluginInfo.get_or_none(
|
||||
name=text, load_status=True, plugin_type=PluginType.NORMAL
|
||||
):
|
||||
image = None
|
||||
if _path.exists():
|
||||
if files := os.listdir(_path):
|
||||
image = _path / random.choice(files)
|
||||
message_list = []
|
||||
if image:
|
||||
message_list.append(image)
|
||||
message_list.append(
|
||||
"桀桀桀,预判到会有 '笨蛋' 把功能名称当命令用,特地前来嘲笑!"
|
||||
f"但还是好心来帮帮你啦!\n请at我发送 '帮助{plugin.name}' 或者"
|
||||
f" '帮助{plugin.id}' 来获取该功能帮助!"
|
||||
)
|
||||
logger.info(
|
||||
"检测到功能名称当命令使用,已发送帮助信息", "功能帮助", session=session
|
||||
)
|
||||
await MessageUtils.build_message(message_list).send(reply_to=True)
|
||||
matcher.stop_propagation()
|
||||
|
||||
image = None
|
||||
if _path.exists():
|
||||
if files := os.listdir(_path):
|
||||
image = _path / random.choice(files)
|
||||
message_list = []
|
||||
if image:
|
||||
message_list.append(image)
|
||||
message_list.append(
|
||||
"桀桀桀,预判到会有 '笨蛋' 把功能名称当命令用,特地前来嘲笑!"
|
||||
f"但还是好心来帮帮你啦!\n请at我发送 '帮助{plugin.name}' 或者"
|
||||
f" '帮助{plugin.id}' 来获取该功能帮助!"
|
||||
)
|
||||
logger.info("检测到功能名称当命令使用,已发送帮助信息", "功能帮助", session=session)
|
||||
await MessageUtils.build_message(message_list).send(reply_to=True)
|
||||
matcher.stop_propagation()
|
||||
|
||||
@ -4,7 +4,7 @@ from nonebot_plugin_alconna import Alconna, Args, Arparma, At, Match, on_alconna
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from playwright.async_api import TimeoutError
|
||||
|
||||
from zhenxun.configs.utils import PluginExtraData
|
||||
from zhenxun.configs.utils import Command, PluginExtraData
|
||||
from zhenxun.models.group_member_info import GroupInfoUser
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.utils.depends import UserName
|
||||
@ -20,7 +20,9 @@ __plugin_meta__ = PluginMetadata(
|
||||
指令:
|
||||
我的信息 ?[at]
|
||||
""".strip(),
|
||||
extra=PluginExtraData(author="HibiKier", version="0.1").dict(),
|
||||
extra=PluginExtraData(
|
||||
author="HibiKier", version="0.1", commands=[Command(command="我的信息")]
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -145,7 +145,7 @@ async def get_user_info(
|
||||
bytes: 图片数据
|
||||
"""
|
||||
platform = PlatformUtils.get_platform(session) or "qq"
|
||||
ava_url = PlatformUtils.get_user_avatar_url(user_id, platform)
|
||||
ava_url = PlatformUtils.get_user_avatar_url(user_id, platform, session.self_id)
|
||||
user = await UserConsole.get_user(user_id, platform)
|
||||
level = await LevelUser.get_user_level(user_id, group_id)
|
||||
sign_level = 0
|
||||
|
||||
@ -49,7 +49,7 @@ def _handle_config(plugin: Plugin, exists_module: list[str]):
|
||||
arg_parser=reg_config.arg_parser,
|
||||
_override=False,
|
||||
)
|
||||
exists_module.append(f"{module}:{reg_config.key}")
|
||||
exists_module.append(f"{module}:{reg_config.key}".lower())
|
||||
|
||||
|
||||
def _generate_simple_config(exists_module: list[str]):
|
||||
@ -62,6 +62,7 @@ def _generate_simple_config(exists_module: list[str]):
|
||||
# 读取用户配置
|
||||
_data = {}
|
||||
_tmp_data = {}
|
||||
exists_module += Config.add_module
|
||||
if SIMPLE_CONFIG_FILE.exists():
|
||||
_data = _yaml.load(SIMPLE_CONFIG_FILE.open(encoding="utf8"))
|
||||
# 将简易配置文件的数据填充到配置文件
|
||||
@ -71,7 +72,7 @@ def _generate_simple_config(exists_module: list[str]):
|
||||
try:
|
||||
if _data.get(module) and k in _data[module].keys():
|
||||
Config.set_config(module, k, _data[module][k])
|
||||
if f"{module}:{k}" in exists_module:
|
||||
if f"{module}:{k}".lower() in exists_module:
|
||||
_tmp_data[module][k] = Config.get_config(module, k)
|
||||
except AttributeError as e:
|
||||
raise AttributeError(f"{e}\n可能为config.yaml配置文件填写不规范") from e
|
||||
|
||||
@ -72,7 +72,10 @@ async def _handle_setting(
|
||||
cost_gold=setting.cost_gold,
|
||||
plugin_type=extra_data.plugin_type,
|
||||
admin_level=extra_data.admin_level,
|
||||
is_show=extra_data.is_show,
|
||||
ignore_prompt=extra_data.ignore_prompt,
|
||||
parent=(plugin.parent_plugin.module_name if plugin.parent_plugin else None),
|
||||
impression=setting.impression,
|
||||
)
|
||||
)
|
||||
if extra_data.limits:
|
||||
|
||||
@ -181,7 +181,7 @@ class Manager:
|
||||
del temp_data["test"]["check_type"]
|
||||
else:
|
||||
for v in temp_data:
|
||||
temp_data[v] = temp_data[v].dict()
|
||||
temp_data[v] = temp_data[v].to_dict()
|
||||
if check_type := temp_data[v].get("check_type"):
|
||||
temp_data[v]["check_type"] = str(check_type)
|
||||
if watch_type := temp_data[v].get("watch_type"):
|
||||
|
||||
@ -7,11 +7,10 @@ from nonebot.params import Depends, RegexGroup
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot.rule import to_me
|
||||
from nonebot_plugin_alconna import Alconna, Option, on_alconna, store_true
|
||||
from nonebot_plugin_session import EventSession
|
||||
from nonebot_plugin_userinfo import EventUserInfo, UserInfo
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
|
||||
from zhenxun.configs.config import BotConfig, Config
|
||||
from zhenxun.configs.utils import PluginExtraData, RegisterConfig
|
||||
from zhenxun.configs.utils import Command, PluginExtraData, RegisterConfig
|
||||
from zhenxun.models.ban_console import BanConsole
|
||||
from zhenxun.models.friend_user import FriendUser
|
||||
from zhenxun.models.group_member_info import GroupInfoUser
|
||||
@ -19,6 +18,7 @@ from zhenxun.services.log import logger
|
||||
from zhenxun.utils.depends import UserName
|
||||
from zhenxun.utils.enum import PluginType
|
||||
from zhenxun.utils.message import MessageUtils
|
||||
from zhenxun.utils.platform import PlatformUtils
|
||||
|
||||
__plugin_meta__ = PluginMetadata(
|
||||
name="昵称系统",
|
||||
@ -36,6 +36,11 @@ __plugin_meta__ = PluginMetadata(
|
||||
version="0.1",
|
||||
plugin_type=PluginType.NORMAL,
|
||||
menu_type="其他",
|
||||
commands=[
|
||||
Command(command="以后叫我 [昵称]"),
|
||||
Command(command="全局昵称设置 [昵称]"),
|
||||
Command(command=f"{BotConfig.self_nickname}我是谁"),
|
||||
],
|
||||
configs=[
|
||||
RegisterConfig(
|
||||
key="BLACK_WORD",
|
||||
@ -46,7 +51,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
type=list[str],
|
||||
)
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
_nickname_matcher = on_regex(
|
||||
@ -119,7 +124,7 @@ def CheckNickname():
|
||||
|
||||
async def dependency(
|
||||
bot: Bot,
|
||||
session: EventSession,
|
||||
session: Uninfo,
|
||||
reg_group: tuple[Any, ...] = RegexGroup(),
|
||||
):
|
||||
black_word = Config.get_config("nickname", "BLACK_WORD")
|
||||
@ -129,7 +134,7 @@ def CheckNickname():
|
||||
await MessageUtils.build_message("叫你空白?叫你虚空?叫你无名??").finish(
|
||||
at_sender=True
|
||||
)
|
||||
if session.id1 in bot.config.superusers:
|
||||
if session.user.id in bot.config.superusers:
|
||||
logger.debug(
|
||||
f"超级用户设置昵称, 跳过合法检测: {name}", "昵称设置", session=session
|
||||
)
|
||||
@ -163,110 +168,106 @@ def CheckNickname():
|
||||
|
||||
@_nickname_matcher.handle(parameterless=[CheckNickname()])
|
||||
async def _(
|
||||
session: EventSession,
|
||||
user_info: UserInfo = EventUserInfo(),
|
||||
session: Uninfo,
|
||||
uname: str = UserName(),
|
||||
reg_group: tuple[Any, ...] = RegexGroup(),
|
||||
):
|
||||
if session.id1:
|
||||
(name,) = reg_group
|
||||
if len(name) < 5 and random.random() < 0.3:
|
||||
name = "~".join(name)
|
||||
if gid := session.id3 or session.id2:
|
||||
await GroupInfoUser.set_user_nickname(
|
||||
session.id1,
|
||||
gid,
|
||||
name,
|
||||
user_info.user_displayname
|
||||
or user_info.user_remark
|
||||
or user_info.user_name,
|
||||
session.platform,
|
||||
)
|
||||
logger.info(f"设置群昵称成功: {name}", "昵称设置", session=session)
|
||||
else:
|
||||
await FriendUser.set_user_nickname(
|
||||
session.id1,
|
||||
name,
|
||||
user_info.user_displayname
|
||||
or user_info.user_remark
|
||||
or user_info.user_name,
|
||||
session.platform,
|
||||
)
|
||||
logger.info(f"设置私聊昵称成功: {name}", "昵称设置", session=session)
|
||||
await MessageUtils.build_message(random.choice(CALL_NAME).format(name)).finish(
|
||||
reply_to=True
|
||||
(name,) = reg_group
|
||||
if len(name) < 5 and random.random() < 0.3:
|
||||
name = "~".join(name)
|
||||
group_id = None
|
||||
if session.group:
|
||||
group_id = session.group.parent.id if session.group.parent else session.group.id
|
||||
if group_id:
|
||||
await GroupInfoUser.set_user_nickname(
|
||||
session.user.id,
|
||||
group_id,
|
||||
name,
|
||||
uname,
|
||||
PlatformUtils.get_platform(session),
|
||||
)
|
||||
await MessageUtils.build_message("用户id为空...").send()
|
||||
logger.info(f"设置群昵称成功: {name}", "昵称设置", session=session)
|
||||
else:
|
||||
await FriendUser.set_user_nickname(
|
||||
session.user.id,
|
||||
name,
|
||||
uname,
|
||||
PlatformUtils.get_platform(session),
|
||||
)
|
||||
logger.info(f"设置私聊昵称成功: {name}", "昵称设置", session=session)
|
||||
await MessageUtils.build_message(random.choice(CALL_NAME).format(name)).finish(
|
||||
reply_to=True
|
||||
)
|
||||
|
||||
|
||||
@_global_nickname_matcher.handle(parameterless=[CheckNickname()])
|
||||
async def _(
|
||||
session: EventSession,
|
||||
session: Uninfo,
|
||||
nickname: str = UserName(),
|
||||
reg_group: tuple[Any, ...] = RegexGroup(),
|
||||
):
|
||||
if session.id1:
|
||||
(name,) = reg_group
|
||||
await FriendUser.set_user_nickname(
|
||||
session.id1,
|
||||
name,
|
||||
nickname,
|
||||
session.platform,
|
||||
)
|
||||
await GroupInfoUser.filter(user_id=session.id1).update(nickname=name)
|
||||
logger.info(f"设置全局昵称成功: {name}", "设置全局昵称", session=session)
|
||||
await MessageUtils.build_message(random.choice(CALL_NAME).format(name)).finish(
|
||||
reply_to=True
|
||||
)
|
||||
await MessageUtils.build_message("用户id为空...").send()
|
||||
(name,) = reg_group
|
||||
await FriendUser.set_user_nickname(
|
||||
session.user.id,
|
||||
name,
|
||||
nickname,
|
||||
PlatformUtils.get_platform(session),
|
||||
)
|
||||
await GroupInfoUser.filter(user_id=session.user.id).update(nickname=name)
|
||||
logger.info(f"设置全局昵称成功: {name}", "设置全局昵称", session=session)
|
||||
await MessageUtils.build_message(random.choice(CALL_NAME).format(name)).finish(
|
||||
reply_to=True
|
||||
)
|
||||
|
||||
|
||||
@_matcher.assign("name")
|
||||
async def _(session: EventSession, user_info: UserInfo = EventUserInfo()):
|
||||
if session.id1:
|
||||
if gid := session.id3 or session.id2:
|
||||
nickname = await GroupInfoUser.get_user_nickname(session.id1, gid)
|
||||
card = user_info.user_displayname or user_info.user_name
|
||||
else:
|
||||
nickname = await FriendUser.get_user_nickname(session.id1)
|
||||
card = user_info.user_name
|
||||
if nickname:
|
||||
await MessageUtils.build_message(
|
||||
random.choice(REMIND).format(nickname)
|
||||
).finish(reply_to=True)
|
||||
else:
|
||||
await MessageUtils.build_message(
|
||||
random.choice(
|
||||
[
|
||||
"没..没有昵称嘛,{}",
|
||||
"啊,你是{}啊,我想叫你的昵称!",
|
||||
"是{}啊,有什么事吗?",
|
||||
"你是{}?",
|
||||
]
|
||||
).format(card)
|
||||
).finish(reply_to=True)
|
||||
await MessageUtils.build_message("用户id为空...").send()
|
||||
async def _(session: Uninfo, uname: str = UserName()):
|
||||
group_id = None
|
||||
if session.group:
|
||||
group_id = session.group.parent.id if session.group.parent else session.group.id
|
||||
if group_id:
|
||||
nickname = await GroupInfoUser.get_user_nickname(session.user.id, group_id)
|
||||
card = uname
|
||||
else:
|
||||
nickname = await FriendUser.get_user_nickname(session.user.id)
|
||||
card = uname
|
||||
if nickname:
|
||||
await MessageUtils.build_message(random.choice(REMIND).format(nickname)).finish(
|
||||
reply_to=True
|
||||
)
|
||||
else:
|
||||
await MessageUtils.build_message(
|
||||
random.choice(
|
||||
[
|
||||
"没..没有昵称嘛,{}",
|
||||
"啊,你是{}啊,我想叫你的昵称!",
|
||||
"是{}啊,有什么事吗?",
|
||||
"你是{}?",
|
||||
]
|
||||
).format(card)
|
||||
).finish(reply_to=True)
|
||||
|
||||
|
||||
@_matcher.assign("cancel")
|
||||
async def _(bot: Bot, session: EventSession, user_info: UserInfo = EventUserInfo()):
|
||||
if session.id1:
|
||||
gid = session.id3 or session.id2
|
||||
if gid:
|
||||
nickname = await GroupInfoUser.get_user_nickname(session.id1, gid)
|
||||
async def _(bot: Bot, session: Uninfo):
|
||||
group_id = None
|
||||
if session.group:
|
||||
group_id = session.group.parent.id if session.group.parent else session.group.id
|
||||
if group_id:
|
||||
nickname = await GroupInfoUser.get_user_nickname(session.user.id, group_id)
|
||||
else:
|
||||
nickname = await FriendUser.get_user_nickname(session.user.id)
|
||||
if nickname:
|
||||
await MessageUtils.build_message(random.choice(CANCEL).format(nickname)).send(
|
||||
reply_to=True
|
||||
)
|
||||
if group_id:
|
||||
await GroupInfoUser.set_user_nickname(session.user.id, group_id, "")
|
||||
else:
|
||||
nickname = await FriendUser.get_user_nickname(session.id1)
|
||||
if nickname:
|
||||
await MessageUtils.build_message(
|
||||
random.choice(CANCEL).format(nickname)
|
||||
).send(reply_to=True)
|
||||
if gid:
|
||||
await GroupInfoUser.set_user_nickname(session.id1, gid, "")
|
||||
else:
|
||||
await FriendUser.set_user_nickname(session.id1, "")
|
||||
await BanConsole.ban(session.id1, gid, 9, 60, bot.self_id)
|
||||
return
|
||||
else:
|
||||
await MessageUtils.build_message("你在做梦吗?你没有昵称啊").finish(
|
||||
reply_to=True
|
||||
)
|
||||
await MessageUtils.build_message("用户id为空...").send()
|
||||
await FriendUser.set_user_nickname(session.user.id, "")
|
||||
await BanConsole.ban(session.user.id, group_id, 9, 60, bot.self_id)
|
||||
return
|
||||
else:
|
||||
await MessageUtils.build_message("你在做梦吗?你没有昵称啊").finish(
|
||||
reply_to=True
|
||||
)
|
||||
|
||||
@ -16,7 +16,9 @@ except ImportError:
|
||||
|
||||
|
||||
try:
|
||||
from nonebot.adapters.qq import Bot # noqa: F401
|
||||
from nonebot.adapters.qq import ( # noqa: F401 # pyright: ignore [reportMissingImports]
|
||||
Bot,
|
||||
)
|
||||
|
||||
nonebot.load_plugins(str((path / "qq_api").resolve()))
|
||||
except ImportError:
|
||||
|
||||
@ -84,7 +84,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
default_status=False,
|
||||
),
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
@ -116,19 +116,19 @@ async def _(
|
||||
session: Uninfo,
|
||||
event: GroupIncreaseNoticeEvent | GroupMemberIncreaseEvent,
|
||||
):
|
||||
user_id = str(event.user_id)
|
||||
group_id = str(event.group_id)
|
||||
if user_id == bot.self_id:
|
||||
if session.user.id == bot.self_id:
|
||||
"""新成员为bot本身"""
|
||||
group, _ = await GroupConsole.get_or_create(
|
||||
group_id=group_id, channel_id__isnull=True
|
||||
group_id=str(event.group_id), channel_id__isnull=True
|
||||
)
|
||||
try:
|
||||
await GroupManager.add_bot(bot, str(event.operator_id), group_id, group)
|
||||
await GroupManager.add_bot(
|
||||
bot, str(event.operator_id), str(event.group_id), group
|
||||
)
|
||||
except ForceAddGroupError as e:
|
||||
await PlatformUtils.send_superuser(bot, e.get_info())
|
||||
else:
|
||||
await GroupManager.add_user(session, bot, user_id, group_id)
|
||||
await GroupManager.add_user(session, bot)
|
||||
|
||||
|
||||
@group_decrease_handle.handle()
|
||||
|
||||
@ -4,6 +4,7 @@ from pathlib import Path
|
||||
import random
|
||||
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot.exception import ActionFailed
|
||||
from nonebot_plugin_alconna import At, UniMessage
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
import ujson as json
|
||||
@ -217,33 +218,45 @@ class GroupManager:
|
||||
msg_list.insert(0, At("user", user_id))
|
||||
logger.info("发送群欢迎消息...", "入群检测", session=session)
|
||||
if msg_list:
|
||||
await MessageUtils.build_message(msg_list).send() # type: ignore
|
||||
else:
|
||||
image = DEFAULT_IMAGE_PATH / random.choice(
|
||||
os.listdir(DEFAULT_IMAGE_PATH)
|
||||
)
|
||||
await MessageUtils.build_message(
|
||||
[
|
||||
"新人快跑啊!!本群现状↓(快使用自定义群欢迎消息!)",
|
||||
image,
|
||||
]
|
||||
).send()
|
||||
await MessageUtils.build_message(msg_list).finish() # type: ignore
|
||||
image = DEFAULT_IMAGE_PATH / random.choice(os.listdir(DEFAULT_IMAGE_PATH))
|
||||
await MessageUtils.build_message(
|
||||
[
|
||||
"新人快跑啊!!本群现状↓(快使用自定义群欢迎消息!)",
|
||||
image,
|
||||
]
|
||||
).send()
|
||||
|
||||
@classmethod
|
||||
async def add_user(cls, session: Uninfo, bot: Bot, user_id: str, group_id: str):
|
||||
async def add_user(cls, session: Uninfo, bot: Bot):
|
||||
"""拉入用户
|
||||
|
||||
参数:
|
||||
session: Uninfo
|
||||
bot: Bot
|
||||
user_id: 用户id
|
||||
group_id: 群组id
|
||||
"""
|
||||
user_id = session.user.id
|
||||
group_id = ""
|
||||
if session.group:
|
||||
if session.group.parent:
|
||||
group_id = session.group.parent.id
|
||||
else:
|
||||
group_id = session.group.id
|
||||
join_time = datetime.now()
|
||||
user_info = await bot.get_group_member_info(group_id=group_id, user_id=user_id)
|
||||
try:
|
||||
user_info = await bot.get_group_member_info(
|
||||
group_id=int(group_id), user_id=int(user_id), no_cache=True
|
||||
)
|
||||
except ActionFailed as e:
|
||||
logger.warning("获取用户信息识别...", e=e)
|
||||
user_info = {"user_id": user_id, "group_id": group_id, "nickname": ""}
|
||||
await GroupInfoUser.update_or_create(
|
||||
user_id=str(user_info["user_id"]),
|
||||
group_id=str(user_info["group_id"]),
|
||||
defaults={"user_name": user_info["nickname"], "user_join_time": join_time},
|
||||
defaults={
|
||||
"user_name": user_info["nickname"],
|
||||
"user_join_time": join_time,
|
||||
},
|
||||
)
|
||||
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功")
|
||||
if not await CommonUtils.task_is_block(
|
||||
@ -312,10 +325,13 @@ class GroupManager:
|
||||
group_id=group_id,
|
||||
)
|
||||
if sub_type == "kick":
|
||||
operator = await bot.get_group_member_info(
|
||||
user_id=int(operator_id), group_id=int(group_id)
|
||||
)
|
||||
operator_name = operator["card"] or operator["nickname"]
|
||||
if operator_id != "0":
|
||||
operator = await bot.get_group_member_info(
|
||||
user_id=int(operator_id), group_id=int(group_id)
|
||||
)
|
||||
operator_name = operator["card"] or operator["nickname"]
|
||||
else:
|
||||
operator_name = ""
|
||||
return f"{user_name} 被 {operator_name} 送走了."
|
||||
elif sub_type == "leave":
|
||||
return f"{user_name}离开了我们..."
|
||||
|
||||
@ -7,6 +7,7 @@ from zhenxun.configs.utils import PluginExtraData
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.utils.enum import PluginType
|
||||
from zhenxun.utils.message import MessageUtils
|
||||
from zhenxun.utils.utils import is_number
|
||||
|
||||
from .data_source import ShopManage
|
||||
|
||||
@ -25,16 +26,16 @@ __plugin_meta__ = PluginMetadata(
|
||||
author="HibiKier",
|
||||
version="0.1",
|
||||
plugin_type=PluginType.SUPERUSER,
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
_matcher = on_alconna(
|
||||
Alconna(
|
||||
"插件商店",
|
||||
Subcommand("add", Args["plugin_id", int | str]),
|
||||
Subcommand("remove", Args["plugin_id", int | str]),
|
||||
Subcommand("add", Args["plugin_id", str]),
|
||||
Subcommand("remove", Args["plugin_id", str]),
|
||||
Subcommand("search", Args["plugin_name_or_author", str]),
|
||||
Subcommand("update", Args["plugin_id", int | str]),
|
||||
Subcommand("update", Args["plugin_id", str]),
|
||||
Subcommand("update_all"),
|
||||
),
|
||||
permission=SUPERUSER,
|
||||
@ -43,14 +44,14 @@ _matcher = on_alconna(
|
||||
)
|
||||
|
||||
_matcher.shortcut(
|
||||
r"添加插件",
|
||||
r"(添加|安装)插件",
|
||||
command="插件商店",
|
||||
arguments=["add", "{%0}"],
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
_matcher.shortcut(
|
||||
r"移除插件",
|
||||
r"(移除|卸载)插件",
|
||||
command="插件商店",
|
||||
arguments=["remove", "{%0}"],
|
||||
prefix=True,
|
||||
@ -90,12 +91,12 @@ async def _(session: EventSession):
|
||||
|
||||
|
||||
@_matcher.assign("add")
|
||||
async def _(session: EventSession, plugin_id: int | str):
|
||||
async def _(session: EventSession, plugin_id: str):
|
||||
try:
|
||||
if isinstance(plugin_id, str):
|
||||
await MessageUtils.build_message(f"正在添加插件 Module: {plugin_id}").send()
|
||||
else:
|
||||
if is_number(plugin_id):
|
||||
await MessageUtils.build_message(f"正在添加插件 Id: {plugin_id}").send()
|
||||
else:
|
||||
await MessageUtils.build_message(f"正在添加插件 Module: {plugin_id}").send()
|
||||
result = await ShopManage.add_plugin(plugin_id)
|
||||
except Exception as e:
|
||||
logger.error(f"添加插件 Id: {plugin_id}失败", "插件商店", session=session, e=e)
|
||||
@ -107,7 +108,7 @@ async def _(session: EventSession, plugin_id: int | str):
|
||||
|
||||
|
||||
@_matcher.assign("remove")
|
||||
async def _(session: EventSession, plugin_id: int | str):
|
||||
async def _(session: EventSession, plugin_id: str):
|
||||
try:
|
||||
result = await ShopManage.remove_plugin(plugin_id)
|
||||
except Exception as e:
|
||||
@ -138,12 +139,12 @@ async def _(session: EventSession, plugin_name_or_author: str):
|
||||
|
||||
|
||||
@_matcher.assign("update")
|
||||
async def _(session: EventSession, plugin_id: int | str):
|
||||
async def _(session: EventSession, plugin_id: str):
|
||||
try:
|
||||
if isinstance(plugin_id, str):
|
||||
await MessageUtils.build_message(f"正在更新插件 Module: {plugin_id}").send()
|
||||
else:
|
||||
if is_number(plugin_id):
|
||||
await MessageUtils.build_message(f"正在更新插件 Id: {plugin_id}").send()
|
||||
else:
|
||||
await MessageUtils.build_message(f"正在更新插件 Module: {plugin_id}").send()
|
||||
result = await ShopManage.update_plugin(plugin_id)
|
||||
except Exception as e:
|
||||
logger.error(f"更新插件 Id: {plugin_id}失败", "插件商店", session=session, e=e)
|
||||
|
||||
@ -14,6 +14,7 @@ from zhenxun.utils.github_utils import GithubUtils
|
||||
from zhenxun.utils.github_utils.models import RepoAPI
|
||||
from zhenxun.utils.http_utils import AsyncHttpx
|
||||
from zhenxun.utils.image_utils import BuildImage, ImageTemplate, RowStyle
|
||||
from zhenxun.utils.utils import is_number
|
||||
|
||||
from .config import BASE_PATH, DEFAULT_GITHUB_URL, EXTRA_GITHUB_URL
|
||||
|
||||
@ -50,7 +51,7 @@ def install_requirement(plugin_path: Path):
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["pip", "install", "-r", str(existing_requirements)],
|
||||
["poetry", "run", "pip", "install", "-r", str(existing_requirements)],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
@ -79,12 +80,17 @@ class ShopManage:
|
||||
返回:
|
||||
dict: 插件信息数据
|
||||
"""
|
||||
default_github_url = await GithubUtils.parse_github_url(
|
||||
DEFAULT_GITHUB_URL
|
||||
).get_raw_download_urls("plugins.json")
|
||||
extra_github_url = await GithubUtils.parse_github_url(
|
||||
EXTRA_GITHUB_URL
|
||||
).get_raw_download_urls("plugins.json")
|
||||
default_github_repo = GithubUtils.parse_github_url(DEFAULT_GITHUB_URL)
|
||||
extra_github_repo = GithubUtils.parse_github_url(EXTRA_GITHUB_URL)
|
||||
for repo_info in [default_github_repo, extra_github_repo]:
|
||||
if await repo_info.update_repo_commit():
|
||||
logger.info(f"获取最新提交: {repo_info.branch}", "插件管理")
|
||||
else:
|
||||
logger.warning(f"获取最新提交失败: {repo_info}", "插件管理")
|
||||
default_github_url = await default_github_repo.get_raw_download_urls(
|
||||
"plugins.json"
|
||||
)
|
||||
extra_github_url = await extra_github_repo.get_raw_download_urls("plugins.json")
|
||||
res = await AsyncHttpx.get(default_github_url)
|
||||
res2 = await AsyncHttpx.get(extra_github_url)
|
||||
|
||||
@ -175,7 +181,7 @@ class ShopManage:
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def add_plugin(cls, plugin_id: int | str) -> str:
|
||||
async def add_plugin(cls, plugin_id: str) -> str:
|
||||
"""添加插件
|
||||
|
||||
参数:
|
||||
@ -217,6 +223,10 @@ class ShopManage:
|
||||
files: list[str]
|
||||
repo_api: RepoAPI
|
||||
repo_info = GithubUtils.parse_github_url(github_url)
|
||||
if await repo_info.update_repo_commit():
|
||||
logger.info(f"获取最新提交: {repo_info.branch}", "插件管理")
|
||||
else:
|
||||
logger.warning(f"获取最新提交失败: {repo_info}", "插件管理")
|
||||
logger.debug(f"成功获取仓库信息: {repo_info}", "插件管理")
|
||||
for repo_api in GithubUtils.iter_api_strategies():
|
||||
try:
|
||||
@ -231,8 +241,9 @@ class ShopManage:
|
||||
raise ValueError("所有API获取插件文件失败,请检查网络连接")
|
||||
if module_path == ".":
|
||||
module_path = ""
|
||||
replace_module_path = module_path.replace(".", "/")
|
||||
files = repo_api.get_files(
|
||||
module_path=module_path.replace(".", "/") + ("" if is_dir else ".py"),
|
||||
module_path=replace_module_path + ("" if is_dir else ".py"),
|
||||
is_dir=is_dir,
|
||||
)
|
||||
download_urls = [await repo_info.get_raw_download_urls(file) for file in files]
|
||||
@ -247,28 +258,35 @@ class ShopManage:
|
||||
else:
|
||||
# 安装依赖
|
||||
plugin_path = base_path / "/".join(module_path.split("."))
|
||||
req_files = repo_api.get_files(REQ_TXT_FILE_STRING, False)
|
||||
req_files.extend(repo_api.get_files("requirement.txt", False))
|
||||
logger.debug(f"获取插件依赖文件列表: {req_files}", "插件管理")
|
||||
req_download_urls = [
|
||||
await repo_info.get_raw_download_urls(file) for file in req_files
|
||||
]
|
||||
req_paths: list[Path | str] = [plugin_path / file for file in req_files]
|
||||
logger.debug(f"插件依赖文件下载路径: {req_paths}", "插件管理")
|
||||
if req_files:
|
||||
result = await AsyncHttpx.gather_download_file(
|
||||
req_download_urls, req_paths
|
||||
try:
|
||||
req_files = repo_api.get_files(
|
||||
f"{replace_module_path}/{REQ_TXT_FILE_STRING}", False
|
||||
)
|
||||
for success in result:
|
||||
if not success:
|
||||
raise Exception("插件依赖文件下载失败")
|
||||
logger.debug(f"插件依赖文件列表: {req_paths}", "插件管理")
|
||||
install_requirement(plugin_path)
|
||||
req_files.extend(
|
||||
repo_api.get_files(f"{replace_module_path}/requirement.txt", False)
|
||||
)
|
||||
logger.debug(f"获取插件依赖文件列表: {req_files}", "插件管理")
|
||||
req_download_urls = [
|
||||
await repo_info.get_raw_download_urls(file) for file in req_files
|
||||
]
|
||||
req_paths: list[Path | str] = [plugin_path / file for file in req_files]
|
||||
logger.debug(f"插件依赖文件下载路径: {req_paths}", "插件管理")
|
||||
if req_files:
|
||||
result = await AsyncHttpx.gather_download_file(
|
||||
req_download_urls, req_paths
|
||||
)
|
||||
for success in result:
|
||||
if not success:
|
||||
raise Exception("插件依赖文件下载失败")
|
||||
logger.debug(f"插件依赖文件列表: {req_paths}", "插件管理")
|
||||
install_requirement(plugin_path)
|
||||
except ValueError as e:
|
||||
logger.warning("未获取到依赖文件路径...", e=e)
|
||||
return True
|
||||
raise Exception("插件下载失败")
|
||||
raise Exception("插件下载失败...")
|
||||
|
||||
@classmethod
|
||||
async def remove_plugin(cls, plugin_id: int | str) -> str:
|
||||
async def remove_plugin(cls, plugin_id: str) -> str:
|
||||
"""移除插件
|
||||
|
||||
参数:
|
||||
@ -344,7 +362,7 @@ class ShopManage:
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def update_plugin(cls, plugin_id: int | str) -> str:
|
||||
async def update_plugin(cls, plugin_id: str) -> str:
|
||||
"""更新插件
|
||||
|
||||
参数:
|
||||
@ -441,12 +459,13 @@ class ShopManage:
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def _resolve_plugin_key(cls, plugin_id: int | str) -> str:
|
||||
async def _resolve_plugin_key(cls, plugin_id: str) -> str:
|
||||
data: dict[str, StorePluginInfo] = await cls.get_data()
|
||||
if isinstance(plugin_id, int):
|
||||
if plugin_id < 0 or plugin_id >= len(data):
|
||||
if is_number(plugin_id):
|
||||
idx = int(plugin_id)
|
||||
if idx < 0 or idx >= len(data):
|
||||
raise ValueError("插件ID不存在...")
|
||||
return list(data.keys())[plugin_id]
|
||||
return list(data.keys())[idx]
|
||||
elif isinstance(plugin_id, str):
|
||||
if plugin_id not in [v.module for k, v in data.items()]:
|
||||
raise ValueError("插件Module不存在...")
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
from nonebot.compat import model_dump
|
||||
from pydantic import BaseModel
|
||||
|
||||
from zhenxun.utils.enum import PluginType
|
||||
@ -31,9 +32,12 @@ class StorePluginInfo(BaseModel):
|
||||
"""插件类型"""
|
||||
is_dir: bool
|
||||
"""是否为文件夹插件"""
|
||||
github_url: str | None
|
||||
github_url: str | None = None
|
||||
"""github链接"""
|
||||
|
||||
@property
|
||||
def plugin_type_name(self):
|
||||
return type2name[self.plugin_type.value]
|
||||
|
||||
def to_dict(self, **kwargs):
|
||||
return model_dump(self, **kwargs)
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
import random
|
||||
import time
|
||||
|
||||
from nonebot import on_message, on_request
|
||||
@ -40,9 +42,17 @@ __plugin_meta__ = PluginMetadata(
|
||||
help="是否自动同意好友添加",
|
||||
type=bool,
|
||||
default_value=False,
|
||||
)
|
||||
),
|
||||
RegisterConfig(
|
||||
module="invite_manager",
|
||||
key="AUTO_ADD_GROUP",
|
||||
value=False,
|
||||
help="是否自动同意邀请入群",
|
||||
type=bool,
|
||||
default_value=False,
|
||||
),
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
@ -81,6 +91,7 @@ async def _(bot: v12Bot | v11Bot, event: FriendRequestEvent, session: EventSessi
|
||||
"好友请求",
|
||||
target=event.user_id,
|
||||
)
|
||||
await asyncio.sleep(random.randint(1, 10))
|
||||
await bot.set_friend_add_request(flag=event.flag, approve=True)
|
||||
await FriendUser.create(
|
||||
user_id=str(user["user_id"]), user_name=user["nickname"]
|
||||
@ -118,10 +129,10 @@ async def _(bot: v12Bot | v11Bot, event: FriendRequestEvent, session: EventSessi
|
||||
async def _(bot: v12Bot | v11Bot, event: GroupRequestEvent, session: EventSession):
|
||||
if event.sub_type != "invite":
|
||||
return
|
||||
if str(event.user_id) in bot.config.superusers:
|
||||
if str(event.user_id) in bot.config.superusers or base_config.get("AUTO_ADD_GROUP"):
|
||||
try:
|
||||
logger.debug(
|
||||
"超级用户自动同意加入群聊",
|
||||
"超级用户自动同意加入群聊或开启自动同意入群",
|
||||
"群聊请求",
|
||||
session=event.user_id,
|
||||
target=event.group_id,
|
||||
@ -154,12 +165,42 @@ async def _(bot: v12Bot | v11Bot, event: GroupRequestEvent, session: EventSessio
|
||||
)
|
||||
except ActionFailed as e:
|
||||
logger.error(
|
||||
"超级用户自动同意加入群聊发生错误",
|
||||
"超超级用户自动同意加入群聊或开启自动同意入群,加入群组发生错误",
|
||||
"群聊请求",
|
||||
session=event.user_id,
|
||||
target=event.group_id,
|
||||
e=e,
|
||||
)
|
||||
if str(event.user_id) not in bot.config.superusers and base_config.get(
|
||||
"AUTO_ADD_GROUP"
|
||||
):
|
||||
# 非超级用户邀请自动加入群组
|
||||
nickname = await FriendUser.get_user_name(str(event.user_id))
|
||||
f = await FgRequest.create(
|
||||
request_type=RequestType.GROUP,
|
||||
platform=session.platform,
|
||||
bot_id=bot.self_id,
|
||||
flag=event.flag,
|
||||
user_id=str(event.user_id),
|
||||
nickname=nickname,
|
||||
group_id=str(event.group_id),
|
||||
handle_type=RequestHandleType.APPROVE,
|
||||
)
|
||||
await PlatformUtils.send_superuser(
|
||||
bot,
|
||||
f"*****一份入群申请*****\n"
|
||||
f"ID:{f.id}\n"
|
||||
f"申请人:{nickname}({event.user_id})\n群聊:"
|
||||
f"{event.group_id}\n邀请日期:{datetime.now().replace(microsecond=0)}\n"
|
||||
"注: 该请求已自动同意",
|
||||
)
|
||||
await asyncio.sleep(random.randint(1, 5))
|
||||
await bot.send_private_msg(
|
||||
user_id=event.user_id,
|
||||
message=f"管理员已开启自动同意群组邀请,请不要让{BotConfig.self_nickname}受委屈哦(狠狠监控)"
|
||||
"\n在群组中 群组管理员与群主 允许使用管理员帮助"
|
||||
"(包括ban与功能开关等)\n请在群组中发送 '管理员帮助'",
|
||||
)
|
||||
elif Timer.check(f"{event.user_id}:{event.group_id}"):
|
||||
logger.debug(
|
||||
f"收录 用户[{event.user_id}] 群聊[{event.group_id}] 群聊请求",
|
||||
|
||||
@ -27,7 +27,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
""".strip(),
|
||||
extra=PluginExtraData(
|
||||
author="HibiKier", version="0.1", plugin_type=PluginType.SUPERUSER
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
default_status=False,
|
||||
)
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
driver = nonebot.get_driver()
|
||||
|
||||
@ -16,8 +16,9 @@ from nonebot_plugin_alconna import (
|
||||
)
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
|
||||
from zhenxun.configs.utils import BaseBlock, PluginExtraData, RegisterConfig
|
||||
from zhenxun.configs.utils import BaseBlock, Command, PluginExtraData, RegisterConfig
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.utils.decorator.shop import NotMeetUseConditionsException
|
||||
from zhenxun.utils.depends import UserName
|
||||
from zhenxun.utils.enum import BlockType, PluginType
|
||||
from zhenxun.utils.exception import GoodsNotFound
|
||||
@ -44,6 +45,14 @@ __plugin_meta__ = PluginMetadata(
|
||||
version="0.1",
|
||||
plugin_type=PluginType.NORMAL,
|
||||
menu_type="商店",
|
||||
commands=[
|
||||
Command(command="我的金币"),
|
||||
Command(command="我的道具"),
|
||||
Command(command="购买道具"),
|
||||
Command(command="使用道具"),
|
||||
Command(command="金币排行"),
|
||||
Command(command="金币总排行"),
|
||||
],
|
||||
limits=[BaseBlock(check_type=BlockType.GROUP)],
|
||||
configs=[
|
||||
RegisterConfig(
|
||||
@ -53,7 +62,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
default_value="zhenxun",
|
||||
)
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
from .goods_register import * # noqa: F403
|
||||
@ -194,6 +203,12 @@ async def _(
|
||||
await MessageUtils.build_message(
|
||||
f"没有找到道具 {name.result} 或道具数量不足..."
|
||||
).send(reply_to=True)
|
||||
except NotMeetUseConditionsException as e:
|
||||
if info := e.get_info():
|
||||
await MessageUtils.build_message(info).finish() # type: ignore
|
||||
await MessageUtils.build_message(
|
||||
f"使用道具 {name.result} 的条件不满足..."
|
||||
).send(reply_to=True)
|
||||
|
||||
|
||||
@_matcher.assign("gold-list")
|
||||
|
||||
@ -7,9 +7,11 @@ from types import MappingProxyType
|
||||
from typing import Any, Literal
|
||||
|
||||
from nonebot.adapters import Bot, Event
|
||||
from nonebot.compat import model_dump
|
||||
from nonebot_plugin_alconna import UniMessage, UniMsg
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from pydantic import BaseModel, create_model
|
||||
from pydantic import BaseModel, Field, create_model
|
||||
from tortoise.expressions import Q
|
||||
|
||||
from zhenxun.models.friend_user import FriendUser
|
||||
from zhenxun.models.goods_info import GoodsInfo
|
||||
@ -30,9 +32,9 @@ from .normal_image import normal_image
|
||||
class Goods(BaseModel):
|
||||
name: str
|
||||
"""商品名称"""
|
||||
before_handle: list[Callable] = []
|
||||
before_handle: list[Callable] = Field(default_factory=list)
|
||||
"""使用前函数"""
|
||||
after_handle: list[Callable] = []
|
||||
after_handle: list[Callable] = Field(default_factory=list)
|
||||
"""使用后函数"""
|
||||
func: Callable | None = None
|
||||
"""使用函数"""
|
||||
@ -71,6 +73,14 @@ class ShopParam(BaseModel):
|
||||
"""Uninfo"""
|
||||
message: UniMsg
|
||||
"""UniMessage"""
|
||||
extra_data: dict[str, Any] = Field(default_factory=dict)
|
||||
"""额外数据"""
|
||||
|
||||
class Config:
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
def to_dict(self, **kwargs):
|
||||
return model_dump(self, **kwargs)
|
||||
|
||||
|
||||
async def gold_rank(
|
||||
@ -111,7 +121,7 @@ async def gold_rank(
|
||||
)
|
||||
data_list.append(
|
||||
[
|
||||
f"{i+1}",
|
||||
f"{i + 1}",
|
||||
(ava_bytes, 30, 30) if platform == "qq" else "",
|
||||
uid2name.get(user[0]),
|
||||
user[1],
|
||||
@ -184,7 +194,6 @@ class ShopManage:
|
||||
"num": num,
|
||||
"text": text,
|
||||
"goods_name": goods.name,
|
||||
"message": message,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
@ -193,8 +202,9 @@ class ShopManage:
|
||||
args: MappingProxyType,
|
||||
param: ShopParam,
|
||||
session: Uninfo,
|
||||
message: UniMsg,
|
||||
**kwargs,
|
||||
) -> list[Any]:
|
||||
) -> dict:
|
||||
"""解析参数
|
||||
|
||||
参数:
|
||||
@ -202,31 +212,30 @@ class ShopManage:
|
||||
param: ShopParam
|
||||
|
||||
返回:
|
||||
list[Any]: 参数
|
||||
dict: 参数
|
||||
"""
|
||||
param_list = []
|
||||
_bot = param.bot
|
||||
param.bot = None
|
||||
param_json = param.dict()
|
||||
param_json["bot"] = _bot
|
||||
for par in args.keys():
|
||||
if par in ["shop_param"]:
|
||||
param_list.append(param)
|
||||
elif par in ["session"]:
|
||||
param_list.append(session)
|
||||
elif par in ["message"]:
|
||||
param_list.append(kwargs.get("message"))
|
||||
elif par not in ["args", "kwargs"]:
|
||||
param_list.append(param_json.get(par))
|
||||
if kwargs.get(par) is not None:
|
||||
del kwargs[par]
|
||||
return param_list
|
||||
param_json = {
|
||||
"bot": _bot,
|
||||
"kwargs": kwargs,
|
||||
**param.to_dict(),
|
||||
**param.extra_data,
|
||||
"session": session,
|
||||
"message": message,
|
||||
}
|
||||
for key in list(param_json.keys()):
|
||||
if key not in args:
|
||||
del param_json[key]
|
||||
return param_json
|
||||
|
||||
@classmethod
|
||||
async def run_before_after(
|
||||
cls,
|
||||
goods: Goods,
|
||||
param: ShopParam,
|
||||
session: Uninfo,
|
||||
message: UniMsg,
|
||||
run_type: Literal["after", "before"],
|
||||
**kwargs,
|
||||
):
|
||||
@ -240,16 +249,19 @@ class ShopManage:
|
||||
fun_list = goods.before_handle if run_type == "before" else goods.after_handle
|
||||
if fun_list:
|
||||
for func in fun_list:
|
||||
args = inspect.signature(func).parameters
|
||||
if args and next(iter(args.keys())) != "kwargs":
|
||||
if args := inspect.signature(func).parameters:
|
||||
if asyncio.iscoroutinefunction(func):
|
||||
await func(*cls.__parse_args(args, param, **kwargs))
|
||||
await func(
|
||||
**cls.__parse_args(args, param, session, message, **kwargs)
|
||||
)
|
||||
else:
|
||||
func(*cls.__parse_args(args, param, **kwargs))
|
||||
func(
|
||||
**cls.__parse_args(args, param, session, message, **kwargs)
|
||||
)
|
||||
elif asyncio.iscoroutinefunction(func):
|
||||
await func(**kwargs)
|
||||
await func()
|
||||
else:
|
||||
func(**kwargs)
|
||||
func()
|
||||
|
||||
@classmethod
|
||||
async def __run(
|
||||
@ -257,6 +269,7 @@ class ShopManage:
|
||||
goods: Goods,
|
||||
param: ShopParam,
|
||||
session: Uninfo,
|
||||
message: UniMsg,
|
||||
**kwargs,
|
||||
) -> str | UniMessage | None:
|
||||
"""运行道具函数
|
||||
@ -270,18 +283,20 @@ class ShopManage:
|
||||
"""
|
||||
args = inspect.signature(goods.func).parameters # type: ignore
|
||||
if goods.func:
|
||||
if args and next(iter(args.keys())) != "kwargs":
|
||||
if args:
|
||||
return (
|
||||
await goods.func(*cls.__parse_args(args, param, session, **kwargs))
|
||||
await goods.func(
|
||||
**cls.__parse_args(args, param, session, message, **kwargs)
|
||||
)
|
||||
if asyncio.iscoroutinefunction(goods.func)
|
||||
else goods.func(*cls.__parse_args(args, param, session, **kwargs))
|
||||
else goods.func(
|
||||
**cls.__parse_args(args, param, session, message, **kwargs)
|
||||
)
|
||||
)
|
||||
if asyncio.iscoroutinefunction(goods.func):
|
||||
return await goods.func(
|
||||
**kwargs,
|
||||
)
|
||||
return await goods.func()
|
||||
else:
|
||||
return goods.func(**kwargs)
|
||||
return goods.func()
|
||||
|
||||
@classmethod
|
||||
async def use(
|
||||
@ -329,12 +344,12 @@ class ShopManage:
|
||||
)
|
||||
if num > param.max_num_limit:
|
||||
return f"{goods_info.goods_name} 单次使用最大数量为{param.max_num_limit}..."
|
||||
await cls.run_before_after(goods, param, "before", **kwargs)
|
||||
result = await cls.__run(goods, param, session, **kwargs)
|
||||
await cls.run_before_after(goods, param, session, message, "before", **kwargs)
|
||||
result = await cls.__run(goods, param, session, message, **kwargs)
|
||||
await UserConsole.use_props(
|
||||
session.user.id, goods_info.uuid, num, PlatformUtils.get_platform(session)
|
||||
)
|
||||
await cls.run_before_after(goods, param, "after", **kwargs)
|
||||
await cls.run_before_after(goods, param, session, message, "after", **kwargs)
|
||||
if not result and param.send_success_msg:
|
||||
result = f"使用道具 {goods.name} {num} 次成功!"
|
||||
return result
|
||||
@ -366,10 +381,14 @@ class ShopManage:
|
||||
"""
|
||||
if uuid in cls.uuid2goods:
|
||||
raise ValueError("该商品使用函数已被注册!")
|
||||
kwargs["send_success_msg"] = send_success_msg
|
||||
kwargs["max_num_limit"] = max_num_limit
|
||||
cls.uuid2goods[uuid] = Goods(
|
||||
model=create_model(f"{uuid}_model", __base__=ShopParam, **kwargs),
|
||||
model=create_model(
|
||||
f"{uuid}_model",
|
||||
__base__=ShopParam,
|
||||
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,
|
||||
before_handle=before_handle,
|
||||
after_handle=after_handle,
|
||||
@ -392,17 +411,19 @@ class ShopManage:
|
||||
返回:
|
||||
str: 返回小
|
||||
"""
|
||||
if name == "神秘药水":
|
||||
return "你们看看就好啦,这是不可能卖给你们的~"
|
||||
if num < 0:
|
||||
return "购买的数量要大于0!"
|
||||
goods_list = await GoodsInfo.annotate().order_by("id").all()
|
||||
goods_list = [
|
||||
goods
|
||||
for goods in goods_list
|
||||
if goods.goods_limit_time > time.time() or goods.goods_limit_time == 0
|
||||
]
|
||||
goods_list = (
|
||||
await GoodsInfo.filter(
|
||||
Q(goods_limit_time__gte=time.time()) | Q(goods_limit_time=0)
|
||||
)
|
||||
.annotate()
|
||||
.order_by("id")
|
||||
.all()
|
||||
)
|
||||
if name.isdigit():
|
||||
if int(name) > len(goods_list) or int(name) <= 0:
|
||||
return "道具编号不存在..."
|
||||
goods = goods_list[int(name) - 1]
|
||||
elif filter_goods := [g for g in goods_list if g.goods_name == name]:
|
||||
goods = filter_goods[0]
|
||||
@ -457,24 +478,42 @@ class ShopManage:
|
||||
user = await UserConsole.get_user(user_id, platform)
|
||||
if not user.props:
|
||||
return None
|
||||
result = await GoodsInfo.filter(uuid__in=user.props.keys()).all()
|
||||
data_list = []
|
||||
uuid2goods = {item.uuid: item for item in result}
|
||||
column_name = ["-", "使用ID", "名称", "数量", "简介"]
|
||||
for i, p in enumerate(user.props):
|
||||
if prop := uuid2goods.get(p):
|
||||
data_list.append(
|
||||
[
|
||||
(ICON_PATH / prop.icon, 33, 33) if prop.icon else "",
|
||||
i,
|
||||
prop.goods_name,
|
||||
user.props[p],
|
||||
prop.goods_description,
|
||||
]
|
||||
)
|
||||
|
||||
user.props = {uuid: count for uuid, count in user.props.items() if count > 0}
|
||||
|
||||
goods_list = await GoodsInfo.filter(uuid__in=user.props.keys()).all()
|
||||
goods_by_uuid = {item.uuid: item for item in goods_list}
|
||||
|
||||
table_rows = []
|
||||
for i, prop_uuid in enumerate(user.props):
|
||||
prop = goods_by_uuid.get(prop_uuid)
|
||||
if not prop:
|
||||
continue
|
||||
|
||||
icon = ""
|
||||
if prop.icon:
|
||||
icon_path = ICON_PATH / prop.icon
|
||||
icon = (icon_path, 33, 33) if icon_path.exists() else ""
|
||||
|
||||
table_rows.append(
|
||||
[
|
||||
icon,
|
||||
i,
|
||||
prop.goods_name,
|
||||
user.props[prop_uuid],
|
||||
prop.goods_description,
|
||||
]
|
||||
)
|
||||
|
||||
if not table_rows:
|
||||
return None
|
||||
|
||||
column_name = ["-", "使用ID", "名称", "数量", "简介"]
|
||||
return await ImageTemplate.table_page(
|
||||
f"{name}的道具仓库", "", column_name, data_list
|
||||
f"{name}的道具仓库",
|
||||
"通过 使用道具[ID/名称] 令道具生效",
|
||||
column_name,
|
||||
table_rows,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
||||
@ -16,18 +16,3 @@ async def _(user_id: str):
|
||||
"shop",
|
||||
)
|
||||
return "使用道具神秘药水成功!你滴金币+1000000!"
|
||||
|
||||
|
||||
@shop_register(
|
||||
name="神秘药水2",
|
||||
price=999999,
|
||||
des="鬼知道会有什么效果,要不试试?",
|
||||
partition="小秘密",
|
||||
)
|
||||
async def _(user_id: str):
|
||||
await UserConsole.add_gold(
|
||||
user_id,
|
||||
1000000,
|
||||
"shop",
|
||||
)
|
||||
return "使用道具神秘药水成功!你滴金币+1000000!"
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
from datetime import datetime
|
||||
import time
|
||||
|
||||
from nonebot_plugin_htmlrender import template_to_pic
|
||||
from pydantic import BaseModel
|
||||
from tortoise.expressions import Q
|
||||
|
||||
from zhenxun.configs.config import BotConfig
|
||||
from zhenxun.configs.path_config import TEMPLATE_PATH
|
||||
@ -18,35 +20,57 @@ class GoodsItem(BaseModel):
|
||||
"""分区名称"""
|
||||
|
||||
|
||||
def get_limit_time(end_time: int):
|
||||
now = int(time.time())
|
||||
if now > end_time:
|
||||
return None
|
||||
current_datetime = datetime.fromtimestamp(now)
|
||||
end_datetime = datetime.fromtimestamp(end_time)
|
||||
time_difference = end_datetime - current_datetime
|
||||
total_seconds = time_difference.total_seconds()
|
||||
hours = int(total_seconds // 3600)
|
||||
minutes = int((total_seconds % 3600) // 60)
|
||||
return f"{hours}:{minutes}"
|
||||
|
||||
|
||||
def get_discount(price: int, discount: float):
|
||||
return None if discount == 1.0 else int(price * discount)
|
||||
|
||||
|
||||
async def html_image() -> bytes:
|
||||
"""构建图片"""
|
||||
goods_list: list[tuple[int, GoodsInfo]] = [
|
||||
(i + 1, goods)
|
||||
for i, goods in enumerate(await GoodsInfo.get_all_goods())
|
||||
if goods.goods_limit_time == 0 or time.time() < goods.goods_limit_time
|
||||
]
|
||||
goods_list = (
|
||||
await GoodsInfo.filter(
|
||||
Q(goods_limit_time__gte=time.time()) | Q(goods_limit_time=0)
|
||||
)
|
||||
.annotate()
|
||||
.order_by("id")
|
||||
.all()
|
||||
)
|
||||
partition_dict: dict[str, list[dict]] = {}
|
||||
for goods in goods_list:
|
||||
if not goods[1].partition:
|
||||
goods[1].partition = "默认分区"
|
||||
if goods[1].partition not in partition_dict:
|
||||
partition_dict[goods[1].partition] = []
|
||||
for idx, goods in enumerate(goods_list):
|
||||
if not goods.partition:
|
||||
goods.partition = "默认分区"
|
||||
if goods.partition not in partition_dict:
|
||||
partition_dict[goods.partition] = []
|
||||
icon = None
|
||||
if goods[1].icon:
|
||||
path = ICON_PATH / goods[1].icon
|
||||
if goods.icon:
|
||||
path = ICON_PATH / goods.icon
|
||||
if path.exists():
|
||||
icon = (
|
||||
"data:image/png;base64,"
|
||||
f"{BuildImage.open(ICON_PATH / goods[1].icon).pic2bs4()[9:]}"
|
||||
f"{BuildImage.open(ICON_PATH / goods.icon).pic2bs4()[9:]}"
|
||||
)
|
||||
partition_dict[goods[1].partition].append(
|
||||
partition_dict[goods.partition].append(
|
||||
{
|
||||
"id": goods[0],
|
||||
"price": goods[1].goods_price,
|
||||
"daily_limit": goods[1].daily_limit or "∞",
|
||||
"name": goods[1].goods_name,
|
||||
"id": idx + 1,
|
||||
"price": goods.goods_price,
|
||||
"discount_price": get_discount(goods.goods_price, goods.goods_discount),
|
||||
"limit_time": get_limit_time(goods.goods_limit_time),
|
||||
"daily_limit": goods.daily_limit or "∞",
|
||||
"name": goods.goods_name,
|
||||
"icon": icon,
|
||||
"description": goods[1].goods_description,
|
||||
"description": goods.goods_description,
|
||||
}
|
||||
)
|
||||
data_list = [
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import time
|
||||
|
||||
from tortoise.expressions import Q
|
||||
|
||||
from zhenxun.configs.path_config import IMAGE_PATH
|
||||
from zhenxun.models.goods_info import GoodsInfo
|
||||
from zhenxun.utils._build_image import BuildImage
|
||||
@ -14,17 +16,19 @@ async def normal_image() -> bytes:
|
||||
返回:
|
||||
BuildImage: 商店图片
|
||||
"""
|
||||
goods_lst = await GoodsInfo.get_all_goods()
|
||||
h = 10
|
||||
_list: list[GoodsInfo] = [
|
||||
goods
|
||||
for goods in goods_lst
|
||||
if goods.goods_limit_time == 0 or time.time() < goods.goods_limit_time
|
||||
]
|
||||
goods_list = (
|
||||
await GoodsInfo.filter(
|
||||
Q(goods_limit_time__gte=time.time()) | Q(goods_limit_time=0)
|
||||
)
|
||||
.annotate()
|
||||
.order_by("id")
|
||||
.all()
|
||||
)
|
||||
# A = BuildImage(1100, h, color="#f9f6f2")
|
||||
total_n = 0
|
||||
image_list = []
|
||||
for idx, goods in enumerate(_list):
|
||||
for idx, goods in enumerate(goods_list):
|
||||
name_image = BuildImage(
|
||||
580, 40, font_size=25, color="#e67b6b", font="CJGaoDeGuo.otf"
|
||||
)
|
||||
|
||||
@ -12,7 +12,12 @@ from nonebot_plugin_alconna import (
|
||||
from nonebot_plugin_apscheduler import scheduler
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
|
||||
from zhenxun.configs.utils import PluginCdBlock, PluginExtraData, RegisterConfig
|
||||
from zhenxun.configs.utils import (
|
||||
Command,
|
||||
PluginCdBlock,
|
||||
PluginExtraData,
|
||||
RegisterConfig,
|
||||
)
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.utils.depends import UserName
|
||||
from zhenxun.utils.message import MessageUtils
|
||||
@ -37,6 +42,12 @@ __plugin_meta__ = PluginMetadata(
|
||||
extra=PluginExtraData(
|
||||
author="HibiKier",
|
||||
version="0.1",
|
||||
commands=[
|
||||
Command(command="签到"),
|
||||
Command(command="我的签到"),
|
||||
Command(command="签到排行"),
|
||||
Command(command="签到总排行"),
|
||||
],
|
||||
configs=[
|
||||
RegisterConfig(
|
||||
module="send_setu",
|
||||
@ -82,7 +93,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
),
|
||||
],
|
||||
limits=[PluginCdBlock()],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ class SignManage:
|
||||
)
|
||||
data_list.append(
|
||||
[
|
||||
f"{i+1}",
|
||||
f"{i + 1}",
|
||||
(bytes, 30, 30) if user[3] == "qq" else "",
|
||||
uid2name.get(user[0]),
|
||||
user[1],
|
||||
|
||||
@ -16,6 +16,7 @@ from zhenxun.models.sign_log import SignLog
|
||||
from zhenxun.models.sign_user import SignUser
|
||||
from zhenxun.utils.http_utils import AsyncHttpx
|
||||
from zhenxun.utils.image_utils import BuildImage
|
||||
from zhenxun.utils.platform import PlatformUtils
|
||||
|
||||
from .config import (
|
||||
SIGN_BACKGROUND_PATH,
|
||||
@ -430,7 +431,9 @@ async def _generate_html_card(
|
||||
)
|
||||
now = datetime.now()
|
||||
data = {
|
||||
"ava_url": session.user.avatar,
|
||||
"ava_url": PlatformUtils.get_user_avatar_url(
|
||||
user.user_id, PlatformUtils.get_platform(session), session.self_id
|
||||
),
|
||||
"name": nickname,
|
||||
"uid": uid,
|
||||
"sign_count": f"{user.sign_count}",
|
||||
|
||||
@ -10,7 +10,7 @@ from nonebot_plugin_alconna import (
|
||||
)
|
||||
from nonebot_plugin_session import EventSession
|
||||
|
||||
from zhenxun.configs.utils import PluginExtraData
|
||||
from zhenxun.configs.utils import Command, PluginExtraData
|
||||
from zhenxun.utils.enum import PluginType
|
||||
from zhenxun.utils.message import MessageUtils
|
||||
|
||||
@ -45,7 +45,16 @@ __plugin_meta__ = PluginMetadata(
|
||||
"全局周功能调用统计",
|
||||
"全局月功能调用统计",
|
||||
""".strip(),
|
||||
).dict(),
|
||||
commands=[
|
||||
Command(command="功能调用统计"),
|
||||
Command(command="日功能调用统计"),
|
||||
Command(command="周功能调用统计"),
|
||||
Command(command="我的功能调用统计"),
|
||||
Command(command="我的日功能调用统计"),
|
||||
Command(command="我的周功能调用统计"),
|
||||
Command(command="我的月功能调用统计"),
|
||||
],
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
usage="""""".strip(),
|
||||
extra=PluginExtraData(
|
||||
author="HibiKier", version="0.1", plugin_type=PluginType.HIDDEN
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
TEMP_LIST = []
|
||||
|
||||
@ -32,7 +32,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
author="",
|
||||
version="0.1",
|
||||
plugin_type=PluginType.SUPERUSER,
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
from .bot_switch import * # noqa: F403
|
||||
|
||||
@ -5,6 +5,7 @@ from nonebot.adapters import Bot
|
||||
from nonebot.params import Command
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot.rule import to_me
|
||||
from nonebot_plugin_alconna import Text as alcText
|
||||
from nonebot_plugin_alconna import UniMsg
|
||||
from nonebot_plugin_session import EventSession
|
||||
@ -38,10 +39,12 @@ __plugin_meta__ = PluginMetadata(
|
||||
)
|
||||
],
|
||||
tasks=[Task(module="broadcast", name="广播")],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
_matcher = on_command("广播", priority=1, permission=SUPERUSER, block=True)
|
||||
_matcher = on_command(
|
||||
"广播", priority=1, permission=SUPERUSER, block=True, rule=to_me()
|
||||
)
|
||||
|
||||
|
||||
@_matcher.handle()
|
||||
|
||||
@ -1,11 +1,8 @@
|
||||
import asyncio
|
||||
import random
|
||||
|
||||
from nonebot.adapters import Bot
|
||||
import nonebot_plugin_alconna as alc
|
||||
|
||||
# from nonebot.adapters.discord import Bot as DiscordBot
|
||||
# from nonebot.adapters.dodo import Bot as DodoBot
|
||||
# from nonebot.adapters.kaiheila import Bot as KaiheilaBot
|
||||
# from nonebot.adapters.onebot.v11 import Bot as v11Bot
|
||||
# from nonebot.adapters.onebot.v12 import Bot as v12Bot
|
||||
from nonebot_plugin_alconna import Image, UniMsg
|
||||
from nonebot_plugin_session import EventSession
|
||||
|
||||
@ -59,6 +56,7 @@ class BroadcastManage:
|
||||
session=session,
|
||||
target=f"{group.group_id}:{group.channel_id}",
|
||||
)
|
||||
await asyncio.sleep(random.randint(1, 3))
|
||||
else:
|
||||
logger.warning("target为空", "广播", session=session)
|
||||
except Exception as e:
|
||||
|
||||
@ -26,7 +26,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
author="HibiKier",
|
||||
version="0.1",
|
||||
plugin_type=PluginType.SUPERUSER,
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
author="HibiKier",
|
||||
version="0.1",
|
||||
plugin_type=PluginType.SUPERUSER,
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
_matcher = on_command(
|
||||
|
||||
@ -21,7 +21,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
author="HibiKier",
|
||||
version="0.1",
|
||||
plugin_type=PluginType.SUPERUSER,
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
_friend_matcher = on_alconna(
|
||||
@ -70,8 +70,6 @@ async def _(
|
||||
msg = f"| UID | 昵称 | 共{len(fl)}个好友\n" + msg
|
||||
await MessageUtils.build_message(msg).send()
|
||||
logger.info("查看好友列表", "好友列表", session=session)
|
||||
except (ApiNotAvailable, AttributeError):
|
||||
await MessageUtils.build_message("Api未实现...").send()
|
||||
except Exception as e:
|
||||
logger.error("好友列表发生错误", "好友列表", session=session, e=e)
|
||||
await MessageUtils.build_message("其他未知错误...").send()
|
||||
@ -90,8 +88,6 @@ async def _(
|
||||
msg = f"| GID | 名称 | 共{len(gl)}个群组\n" + msg
|
||||
await MessageUtils.build_message(msg).send()
|
||||
logger.info("查看群组列表", "群组列表", session=session)
|
||||
except (ApiNotAvailable, AttributeError):
|
||||
await MessageUtils.build_message("Api未实现...").send()
|
||||
except Exception as e:
|
||||
logger.error("查看群组列表发生错误", "群组列表", session=session, e=e)
|
||||
await MessageUtils.build_message("其他未知错误...").send()
|
||||
|
||||
@ -53,7 +53,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
author="HibiKier",
|
||||
version="0.1",
|
||||
plugin_type=PluginType.SUPERUSER,
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
type=int,
|
||||
),
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
_matcher = on_alconna(
|
||||
|
||||
@ -16,6 +16,7 @@ from nonebot_plugin_alconna import (
|
||||
)
|
||||
from nonebot_plugin_session import EventSession
|
||||
|
||||
from zhenxun.configs.config import BotConfig
|
||||
from zhenxun.configs.path_config import IMAGE_PATH
|
||||
from zhenxun.configs.utils import PluginExtraData
|
||||
from zhenxun.models.fg_request import FgRequest
|
||||
@ -46,7 +47,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
author="HibiKier",
|
||||
version="0.1",
|
||||
plugin_type=PluginType.SUPERUSER,
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
@ -134,14 +135,15 @@ async def _(
|
||||
"r": RequestHandleType.REFUSED,
|
||||
"i": RequestHandleType.IGNORE,
|
||||
}
|
||||
req = None
|
||||
handle_type = type_dict[handle[-1]]
|
||||
try:
|
||||
if handle_type == RequestHandleType.APPROVE:
|
||||
await FgRequest.approve(bot, id)
|
||||
req = await FgRequest.approve(bot, id)
|
||||
if handle_type == RequestHandleType.REFUSED:
|
||||
await FgRequest.refused(bot, id)
|
||||
req = await FgRequest.refused(bot, id)
|
||||
if handle_type == RequestHandleType.IGNORE:
|
||||
await FgRequest.ignore(id)
|
||||
req = await FgRequest.ignore(id)
|
||||
except NotFoundError:
|
||||
await MessageUtils.build_message("未发现此id的请求...").finish(reply_to=True)
|
||||
except Exception:
|
||||
@ -149,7 +151,14 @@ async def _(
|
||||
reply_to=True
|
||||
)
|
||||
logger.info("处理请求", arparma.header_result, session=session)
|
||||
await MessageUtils.build_message("成功处理请求!").finish(reply_to=True)
|
||||
await MessageUtils.build_message("成功处理请求!").send(reply_to=True)
|
||||
if req and handle_type == RequestHandleType.APPROVE:
|
||||
await bot.send_private_msg(
|
||||
user_id=req.user_id,
|
||||
message=f"管理员已同意此次群组邀请,请不要让{BotConfig.self_nickname}受委屈哦(狠狠监控)"
|
||||
"\n在群组中 群组管理员与群主 允许使用管理员帮助"
|
||||
"(包括ban与功能开关等)\n请在群组中发送 '管理员帮助'",
|
||||
)
|
||||
|
||||
|
||||
@_read_matcher.handle()
|
||||
|
||||
@ -36,7 +36,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
author="HibiKier",
|
||||
version="0.1",
|
||||
plugin_type=PluginType.SUPERUSER,
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
default_value="zhenxun",
|
||||
)
|
||||
],
|
||||
).dict(),
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
_matcher = on_alconna(
|
||||
|
||||
@ -15,7 +15,8 @@ async def get_task() -> dict[str, str] | None:
|
||||
return {
|
||||
"name": "被动技能",
|
||||
"description": "控制群组中的被动技能状态",
|
||||
"usage": "通过 开启/关闭群被动 来控制群被动 <br> ---------- <br> "
|
||||
"usage": "通过 开启/关闭群被动 来控制群被动 <br>"
|
||||
+ " 示例:开启/关闭群被动早晚安 <br> ---------- <br> "
|
||||
+ "<br>".join([task.name for task in task_list]),
|
||||
}
|
||||
return None
|
||||
|
||||
114
zhenxun/builtin_plugins/superuser/super_power.py
Normal file
114
zhenxun/builtin_plugins/superuser/super_power.py
Normal file
@ -0,0 +1,114 @@
|
||||
from decimal import Decimal
|
||||
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot_plugin_alconna import Alconna, Args, Arparma, At, Field, on_alconna
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
|
||||
from zhenxun.configs.utils import PluginExtraData
|
||||
from zhenxun.models.sign_user import SignUser
|
||||
from zhenxun.models.user_console import UserConsole
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.utils.enum import PluginType
|
||||
from zhenxun.utils.message import MessageUtils
|
||||
from zhenxun.utils.platform import PlatformUtils
|
||||
|
||||
__plugin_meta__ = PluginMetadata(
|
||||
name="高贵的作弊器",
|
||||
description="这是一个作弊器,设置用户金币数量和好感度",
|
||||
usage="""
|
||||
金币设置 100(金币数量) @用户
|
||||
好感度设置 100(好感度) @用户
|
||||
""".strip(),
|
||||
extra=PluginExtraData(
|
||||
author="HibiKier",
|
||||
version="0.1",
|
||||
plugin_type=PluginType.SUPERUSER,
|
||||
).to_dict(),
|
||||
)
|
||||
|
||||
_gold_matcher = on_alconna(
|
||||
Alconna(
|
||||
"金币设置",
|
||||
Args[
|
||||
"gold",
|
||||
int,
|
||||
Field(
|
||||
missing_tips=lambda: "请在命令后跟随金币数量!",
|
||||
unmatch_tips=lambda _: "金币数量必须为数字!",
|
||||
),
|
||||
][
|
||||
"at_user",
|
||||
At,
|
||||
Field(
|
||||
missing_tips=lambda: "必须要at一名指定用户!",
|
||||
),
|
||||
],
|
||||
),
|
||||
skip_for_unmatch=False,
|
||||
permission=SUPERUSER,
|
||||
priority=5,
|
||||
block=True,
|
||||
)
|
||||
|
||||
|
||||
_impression_matcher = on_alconna(
|
||||
Alconna(
|
||||
"好感度设置",
|
||||
Args[
|
||||
"impression",
|
||||
float,
|
||||
Field(
|
||||
missing_tips=lambda: "请在命令后跟随好感度!",
|
||||
unmatch_tips=lambda _: "好感度数量必须为数字!",
|
||||
),
|
||||
][
|
||||
"at_user",
|
||||
At,
|
||||
Field(
|
||||
missing_tips=lambda: "必须要at一名指定用户!",
|
||||
),
|
||||
],
|
||||
),
|
||||
skip_for_unmatch=False,
|
||||
permission=SUPERUSER,
|
||||
priority=5,
|
||||
block=True,
|
||||
)
|
||||
|
||||
|
||||
@_gold_matcher.handle()
|
||||
async def _(session: Uninfo, arparma: Arparma, gold: int, at_user: At):
|
||||
user = await UserConsole.get_user(
|
||||
at_user.target, PlatformUtils.get_platform(session)
|
||||
)
|
||||
user.gold = gold
|
||||
await user.save(update_fields=["gold"])
|
||||
await MessageUtils.build_message(
|
||||
["成功将用户", at_user, f"的金币设置为 {gold}"]
|
||||
).send(reply_to=True)
|
||||
logger.info(
|
||||
f"成功将用户{at_user.target}的金币设置为{gold}",
|
||||
arparma.header_result,
|
||||
session=session,
|
||||
)
|
||||
|
||||
|
||||
@_impression_matcher.handle()
|
||||
async def _(session: Uninfo, arparma: Arparma, impression: float, at_user: At):
|
||||
platform = PlatformUtils.get_platform(session)
|
||||
user_console = await UserConsole.get_user(at_user.target, platform)
|
||||
user, _ = await SignUser.get_or_create(
|
||||
user_id=at_user.target,
|
||||
defaults={"user_console": user_console, "platform": platform},
|
||||
)
|
||||
user.impression = Decimal(impression)
|
||||
await user.save(update_fields=["impression"])
|
||||
await MessageUtils.build_message(
|
||||
["成功将用户", at_user, f"的好感度设置为 {impression}"]
|
||||
).send(reply_to=True)
|
||||
logger.info(
|
||||
f"成功将用户{at_user.target}的好感度设置为{impression}",
|
||||
arparma.header_result,
|
||||
session=session,
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user