26 Commits

Author SHA1 Message Date
suyiiyii 6e28ad3502 🔧 更新默认UA为Windows平台 2024-10-23 18:24:40 +08:00
洛初 40f9bc817f feat(ISSUE_TEMPLATE): 修改问题报告模板 (#630)
test-build / Build Frontend (push) Has been cancelled
test-build / Smoke-test Coverage (macos-latest, 3.10) (push) Has been cancelled
test-build / Smoke-test Coverage (macos-latest, 3.11) (push) Has been cancelled
test-build / Smoke-test Coverage (macos-latest, 3.12) (push) Has been cancelled
test-build / Smoke-test Coverage (ubuntu-latest, 3.10) (push) Has been cancelled
test-build / Smoke-test Coverage (ubuntu-latest, 3.11) (push) Has been cancelled
test-build / Smoke-test Coverage (ubuntu-latest, 3.12) (push) Has been cancelled
test-build / Smoke-test Coverage (windows-latest, 3.10) (push) Has been cancelled
test-build / Smoke-test Coverage (windows-latest, 3.11) (push) Has been cancelled
test-build / Smoke-test Coverage (windows-latest, 3.12) (push) Has been cancelled
test-build / All-test Coverage (macos-latest, 3.10) (push) Has been cancelled
test-build / All-test Coverage (macos-latest, 3.11) (push) Has been cancelled
test-build / All-test Coverage (macos-latest, 3.12) (push) Has been cancelled
test-build / All-test Coverage (ubuntu-latest, 3.10) (push) Has been cancelled
test-build / All-test Coverage (ubuntu-latest, 3.11) (push) Has been cancelled
test-build / All-test Coverage (ubuntu-latest, 3.12) (push) Has been cancelled
test-build / All-test Coverage (windows-latest, 3.10) (push) Has been cancelled
test-build / All-test Coverage (windows-latest, 3.11) (push) Has been cancelled
test-build / All-test Coverage (windows-latest, 3.12) (push) Has been cancelled
pydantic1-compat-test / pydantic1 test (ubuntu-latest, 3.11) (push) Has been cancelled
Ruff Lint / Ruff Lint (push) Has been cancelled
test-build / Docker main (push) Has been cancelled
test-build / Docker main sentry (push) Has been cancelled
*  feat(ISSUE_TEMPLATE): 修改问题报告模板 

  feat(ISSUE_TEMPLATE): 修改问题报告模板

* 💄 auto fix by pre-commit hooks

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-10-03 10:31:47 +08:00
github-actions[bot] f416b249f7 📝 Update changelog 2024-10-03 02:31:09 +00:00
suyiiyii ec6fe2679d 👷 将自动化工具中的 yarn 替换为 pnpm (#634)
* 👷 将自动化工具中的 yarn 替换为 pnpm

* 🐛 写串台了艹

* 🐛 最讨厌调试 action 了 (
2024-10-03 10:29:57 +08:00
github-actions[bot] 19b25552d0 📝 Update changelog 2024-10-01 07:38:45 +00:00
洛梧藤 85b5ab3868 📝 小刻食堂剪彩文档 (#636) 2024-10-01 15:38:16 +08:00
felinae98 cf6b7fcd6d 📌 pin eslint to 8
test-build / Build Frontend (push) Has been cancelled
test-build / Smoke-test Coverage (macos-latest, 3.10) (push) Has been cancelled
test-build / Smoke-test Coverage (macos-latest, 3.11) (push) Has been cancelled
test-build / Smoke-test Coverage (macos-latest, 3.12) (push) Has been cancelled
test-build / Smoke-test Coverage (ubuntu-latest, 3.10) (push) Has been cancelled
test-build / Smoke-test Coverage (ubuntu-latest, 3.11) (push) Has been cancelled
test-build / Smoke-test Coverage (ubuntu-latest, 3.12) (push) Has been cancelled
test-build / Smoke-test Coverage (windows-latest, 3.10) (push) Has been cancelled
test-build / Smoke-test Coverage (windows-latest, 3.11) (push) Has been cancelled
test-build / Smoke-test Coverage (windows-latest, 3.12) (push) Has been cancelled
test-build / All-test Coverage (macos-latest, 3.10) (push) Has been cancelled
test-build / All-test Coverage (macos-latest, 3.11) (push) Has been cancelled
test-build / All-test Coverage (macos-latest, 3.12) (push) Has been cancelled
test-build / All-test Coverage (ubuntu-latest, 3.10) (push) Has been cancelled
test-build / All-test Coverage (ubuntu-latest, 3.11) (push) Has been cancelled
test-build / All-test Coverage (ubuntu-latest, 3.12) (push) Has been cancelled
test-build / All-test Coverage (windows-latest, 3.10) (push) Has been cancelled
test-build / All-test Coverage (windows-latest, 3.11) (push) Has been cancelled
test-build / All-test Coverage (windows-latest, 3.12) (push) Has been cancelled
pydantic1-compat-test / pydantic1 test (ubuntu-latest, 3.11) (push) Has been cancelled
Ruff Lint / Ruff Lint (push) Has been cancelled
test-build / Docker main (push) Has been cancelled
test-build / Docker main sentry (push) Has been cancelled
2024-09-21 12:19:54 +08:00
renovate[bot] 2c70d3c44e ⬆️ Update all non-major dependencies (#624)
* ⬆️ Update all non-major dependencies

* 💄 auto fix by pre-commit hooks

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-09-19 13:51:41 +08:00
dependabot[bot] d5c31394df ⬆️ Bump vite from 5.4.2 to 5.4.6 (#625)
* ⬆️ Bump vite from 5.4.2 to 5.4.6

Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.2 to 5.4.6.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.6/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.6/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* 💄 auto fix by pre-commit hooks

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-09-19 11:19:54 +08:00
github-actions[bot] 908de2c5ca 🔖 Release 0.9.4 2024-09-17 15:10:51 +00:00
felinae98 76be8454f3 🔖 release 0.9.4 2024-09-17 23:09:39 +08:00
github-actions[bot] 7845ef8c74 📝 Update changelog 2024-09-17 14:59:38 +00:00
Azide 088e7a439f 新增可以在 fsm 抛出错误后重置 fsm 的装饰器工具 2024-09-17 22:59:09 +08:00
renovate[bot] ab5236ee37 ⬆️ Update all non-major dependencies (#621)
* ⬆️ Update all non-major dependencies

* 💄 auto fix by pre-commit hooks

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-09-12 13:28:17 +08:00
pre-commit-ci[bot] ded3e34259 ⬆️ auto update by pre-commit hooks (#620)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.6.0 → v0.6.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.0...v0.6.3)
- [github.com/pre-commit/mirrors-eslint: v9.8.0 → v9.9.1](https://github.com/pre-commit/mirrors-eslint/compare/v9.8.0...v9.9.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-09-03 13:35:36 +08:00
renovate[bot] 68f7e3b72a ⬆️ Update all non-major dependencies (#595)
* ⬆️ Update all non-major dependencies

* 💄 auto fix by pre-commit hooks

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-09-03 13:34:49 +08:00
github-actions[bot] ccbed746da 📝 Update changelog 2024-09-01 14:34:29 +00:00
dependabot[bot] c523b3a811 ⬆️ Bump webpack from 5.88.2 to 5.94.0 in /admin-frontend (#619)
Bumps [webpack](https://github.com/webpack/webpack) from 5.88.2 to 5.94.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.88.2...v5.94.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-01 22:33:03 +08:00
suyiiyii d6205867b8 无权限用户尝试添加订阅时返回提示信息 (#617)
*  无权限用户尝试添加订阅时返回提示信息

*  添加no_permission_matcher相关的单元测试

* 🐛 优化无权限提示的排版

* 🐛 移除没有必要的命令
2024-09-01 22:32:47 +08:00
github-actions[bot] 83cd0a741e 📝 Update changelog 2024-09-01 14:30:29 +00:00
Azide b8b49a5ce5 🐛 B站请求策略阶段行为优化 (#610)
* 🐛 调整ruff的pytest警告

* 🐛 调整导入关系警告

* 🐛 删除奇怪无用的赋值和取值逻辑

*  不同测试部分所用变量应加以区分

* 🐛 subs_io model添加默认值

* 🐛 修完所有的 ruff PT001 警告

* 🔧 按ruff建议修改ruff配置

warning: The top-level linter settings are deprecated in favour of their counterparts in the `lint` section. Please update the following options in `pyproject.toml`:
  - 'ignore' -> 'lint.ignore'
  - 'select' -> 'lint.select'

* 🔊 降低B站请求策略非Raise阶段API352的日志等级

* 🐛 Raise阶段应该 raise err

* 🔊 日志添加平台名

* 🐛 bzhanhan调度继续降低至60s

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-09-01 22:30:02 +08:00
github-actions[bot] afcc536334 📝 Update changelog 2024-09-01 14:24:42 +00:00
suyiiyii cf38500be7 🐛 Rss 不再删除格式化字符 2024-09-01 22:23:02 +08:00
github-actions[bot] 7d80b44d2a 📝 Update changelog 2024-08-30 02:26:50 +00:00
uy_sun 60e6f05cf4 fix tests 2024-08-30 10:26:22 +08:00
felinae98 8a21ca2a1c 🐛 forbid adding platform that needs browser in no-browser env 2024-08-30 10:26:22 +08:00
32 changed files with 11108 additions and 8501 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
"features": { "features": {
"ghcr.io/devcontainers-contrib/features/poetry:2": {} "ghcr.io/devcontainers-contrib/features/poetry:2": {}
}, },
"postCreateCommand": "poetry config virtualenvs.in-project true && poetry install -E all && poetry run pre-commit install && yarn install", "postCreateCommand": "poetry config virtualenvs.in-project true && poetry install -E all && poetry run pre-commit install && npm install -g pnpm && pnpm install",
"customizations": { "customizations": {
"vscode": { "vscode": {
"settings": { "settings": {
+61
View File
@@ -0,0 +1,61 @@
name: 问题报告
description: 我遇到了问题
body:
- type: markdown
id: environment
attributes:
value: |
## 环境
- type: input
id: nonebot_bison_version
attributes:
label: nonebot-bison 版本
description: 请填写 nonebot-bison 的版本
- type: input
id: nonebot_version
attributes:
label: nonebot 版本
description: 请填写 nonebot 的版本
- type: dropdown
id: installation_method
attributes:
label: 安装方式
description: 请选择安装方式
options:
- 通过 nb-cli 安装
- 使用 poetry/pdm 等现代包管理器安装
- 通过 pip install 安装
- 克隆或下载项目直接使用
- type: input
id: operating_system
attributes:
label: 操作系统
description: 请填写操作系统
- type: textarea
id: issue_description
attributes:
label: 问题
description: 请在这里描述你遇到的问题
- type: textarea
id: logs
attributes:
label: 日志
description: 请在这里粘贴你的日志
render: shell
- type: checkboxes
id: confirmations
attributes:
label: 确认
options:
- label: 我搜索过了 issue,但是并没有发现过与我类似的问题
required: true
- label: 我确认在日志中去掉了敏感信息
required: true
-31
View File
@@ -1,31 +0,0 @@
---
name: 问题报告
about: 我遇到了问题
title: ""
labels: ""
assignees: ""
---
## 环境
- nonebot-bison 版本:
- nonebot 版本:
- 安装方式:(以下方式的一种或者其他方式)
1. 通过 nb-cli 安装
2. 使用 poetry/pdm 等现代包管理器安装
3. 通过 pip install 安装
4. 克隆或下载项目直接使用
- 操作系统:
## 问题
请在这里描述你遇到的问题
## 日志
```
请在这里粘贴你的日志
```
- [ ] 我搜索过了 issue,但是并没有发现过与我类似的问题
- [ ] 我确认在日志中去掉了敏感信息
+2 -2
View File
@@ -10,5 +10,5 @@ runs:
- name: Build Frontend - name: Build Frontend
shell: bash shell: bash
run: | run: |
yarn install pnpm install
yarn docs:build pnpm docs:build
+2 -2
View File
@@ -11,5 +11,5 @@ runs:
shell: bash shell: bash
working-directory: ./admin-frontend working-directory: ./admin-frontend
run: | run: |
yarn install pnpm install
yarn build pnpm build
+9 -4
View File
@@ -8,11 +8,16 @@ runs:
with: with:
node-version: "20" node-version: "20"
- id: yarn-cache-dir-path - name: Set Up Pnpm
run: echo "::set-output name=dir::$(yarn cache dir)" uses: pnpm/action-setup@v4
with:
version: 9
- id: pnpm-cache-dir-path
run: echo "::set-output name=dir::$(pnpm store path)"
shell: bash shell: bash
- uses: actions/cache@v4 - uses: actions/cache@v4
with: with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }} path: ${{ steps.pnpm-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
+2 -2
View File
@@ -7,7 +7,7 @@ ci:
autoupdate_commit_msg: ":arrow_up: auto update by pre-commit hooks" autoupdate_commit_msg: ":arrow_up: auto update by pre-commit hooks"
repos: repos:
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.0 rev: v0.6.3
hooks: hooks:
- id: ruff - id: ruff
args: [--fix, --exit-non-zero-on-fix] args: [--fix, --exit-non-zero-on-fix]
@@ -34,7 +34,7 @@ repos:
stages: [commit] stages: [commit]
- repo: https://github.com/pre-commit/mirrors-eslint - repo: https://github.com/pre-commit/mirrors-eslint
rev: v9.8.0 rev: v9.9.1
hooks: hooks:
- id: eslint - id: eslint
additional_dependencies: additional_dependencies:
+11
View File
@@ -2,8 +2,19 @@
## 最近更新 ## 最近更新
### 文档
- 📝 小刻食堂剪彩文档 [@phidiaLam](https://github.com/phidiaLam) ([#636](https://github.com/MountainDash/nonebot-bison/pull/636))
## v0.9.4
### Bug 修复 ### Bug 修复
- FSM 内部执行外部函数出现异常时不应崩溃 [@AzideCupric](https://github.com/AzideCupric) ([#616](https://github.com/MountainDash/nonebot-bison/pull/616))
- 无权限用户尝试添加订阅时返回提示信息 [@suyiiyii](https://github.com/suyiiyii) ([#617](https://github.com/MountainDash/nonebot-bison/pull/617))
- B站请求策略阶段行为优化 [@AzideCupric](https://github.com/AzideCupric) ([#610](https://github.com/MountainDash/nonebot-bison/pull/610))
- Rss 不再删除格式化字符 [@suyiiyii](https://github.com/suyiiyii) ([#615](https://github.com/MountainDash/nonebot-bison/pull/615))
- forbid adding platform that needs browser in no-browser env [@felinae98](https://github.com/felinae98) ([#609](https://github.com/MountainDash/nonebot-bison/pull/609))
- 修正项目的代码警告 [@AzideCupric](https://github.com/AzideCupric) ([#614](https://github.com/MountainDash/nonebot-bison/pull/614)) - 修正项目的代码警告 [@AzideCupric](https://github.com/AzideCupric) ([#614](https://github.com/MountainDash/nonebot-bison/pull/614))
- 修复 anonymous_site() 无法正确工作的问题 [@felinae98](https://github.com/felinae98) ([#606](https://github.com/MountainDash/nonebot-bison/pull/606)) - 修复 anonymous_site() 无法正确工作的问题 [@felinae98](https://github.com/felinae98) ([#606](https://github.com/MountainDash/nonebot-bison/pull/606))
+18 -18
View File
@@ -5,26 +5,26 @@
"homepage": "bison", "homepage": "bison",
"proxy": "http://127.0.0.1:8080", "proxy": "http://127.0.0.1:8080",
"dependencies": { "dependencies": {
"@arco-design/web-react": "^2.63.1", "@arco-design/web-react": "^2.64.0",
"@babel/core": "^7.24.7", "@babel/core": "^7.25.2",
"@babel/plugin-syntax-flow": "^7.24.7", "@babel/plugin-syntax-flow": "^7.24.7",
"@babel/plugin-transform-react-jsx": "^7.24.7", "@babel/plugin-transform-react-jsx": "^7.25.2",
"@reduxjs/toolkit": "^1.9.7", "@reduxjs/toolkit": "^1.9.7",
"@testing-library/dom": "^10.4.0", "@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.0.0", "@testing-library/react": "^16.0.1",
"@testing-library/user-event": "^14.5.2", "@testing-library/user-event": "^14.5.2",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.13",
"@types/node": "^20.14.10", "@types/node": "^20.16.5",
"@types/react": "^18.3.3", "@types/react": "^18.3.7",
"@types/react-dom": "^18.3.0", "@types/react-dom": "^18.3.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-redux": "^9.1.2", "react-redux": "^9.1.2",
"react-router-dom": "^6.24.1", "react-router-dom": "^6.26.2",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"redux": "^5.0.1", "redux": "^5.0.1",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"typescript": "^5.5.4", "typescript": "^5.6.2",
"web-vitals": "^3.5.2" "web-vitals": "^3.5.2"
}, },
"scripts": { "scripts": {
@@ -53,17 +53,17 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@testing-library/jest-dom": "^6.4.6", "@testing-library/jest-dom": "^6.5.0",
"@typescript-eslint/eslint-plugin": "^8.0.0", "@typescript-eslint/eslint-plugin": "^8.6.0",
"@typescript-eslint/parser": "^8.0.0", "@typescript-eslint/parser": "^8.6.0",
"eslint": "^9.6.0", "eslint": "^8.57.1",
"eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^18.0.0", "eslint-config-airbnb-typescript": "^18.0.0",
"eslint-import-resolver-typescript": "^3.6.1", "eslint-import-resolver-typescript": "^3.6.3",
"eslint-plugin-import": "^2.29.1", "eslint-plugin-import": "^2.30.0",
"eslint-plugin-jsx-a11y": "^6.9.0", "eslint-plugin-jsx-a11y": "^6.10.0",
"eslint-plugin-react": "^7.34.3", "eslint-plugin-react": "^7.36.1",
"eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-redux": "^4.1.0" "eslint-plugin-react-redux": "^4.2.0"
} }
} }
+7980 -6040
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -22,7 +22,7 @@ BISON_SKIP_BROWSER_CHECK=false
BISON_USE_PIC_MERGE=0 BISON_USE_PIC_MERGE=0
BISON_RESEND_TIMES=0 BISON_RESEND_TIMES=0
BISON_PROXY= BISON_PROXY=
BISON_UA=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36 BISON_UA=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0
BISON_SHOW_NETWORK_WARNING=true BISON_SHOW_NETWORK_WARNING=true
BISON_PLATFORM_THEME='{}' BISON_PLATFORM_THEME='{}'
+3 -2
View File
@@ -1,7 +1,8 @@
FROM node:20.15.1 as frontend FROM node:20.17.0 as frontend
ADD . /app ADD . /app
WORKDIR /app/admin-frontend WORKDIR /app/admin-frontend
RUN yarn && yarn build RUN npm install -g pnpm
RUN pnpm install && pnpm build
FROM python:3.11 FROM python:3.11
RUN python3 -m pip install poetry && poetry config virtualenvs.create false RUN python3 -m pip install poetry && poetry config virtualenvs.create false
+1 -1
View File
@@ -1,4 +1,4 @@
# syntax=docker/dockerfile:1.8 # syntax=docker/dockerfile:1.10
FROM python:3.11-slim-bullseye as base FROM python:3.11-slim-bullseye as base
FROM base as builder FROM base as builder
+1 -1
View File
@@ -1,4 +1,4 @@
# syntax=docker/dockerfile:1.8 # syntax=docker/dockerfile:1.10
FROM python:3.11-slim-bullseye as base FROM python:3.11-slim-bullseye as base
FROM base as builder FROM base as builder
+1 -1
View File
@@ -70,7 +70,7 @@ highlights:
details: 一个由玩家创造的幻想世界 details: 一个由玩家创造的幻想世界
link: https://adsrff.web.sdo.com/web1/ link: https://adsrff.web.sdo.com/web1/
- title: 小刻食堂 (即将支持) - title: 小刻食堂
details: 实时获取鹰角发的动态 details: 实时获取鹰角发的动态
link: https://www.ceobecanteen.top link: https://www.ceobecanteen.top
+13
View File
@@ -3,6 +3,7 @@ from pkgutil import iter_modules
from collections import defaultdict from collections import defaultdict
from importlib import import_module from importlib import import_module
from ..plugin_config import plugin_config
from .platform import Platform, make_no_target_group from .platform import Platform, make_no_target_group
_package_dir = str(Path(__file__).resolve().parent) _package_dir = str(Path(__file__).resolve().parent)
@@ -22,3 +23,15 @@ for name, platform_list in _platform_list.items():
platform_manager[name] = platform_list[0] platform_manager[name] = platform_list[0]
else: else:
platform_manager[name] = make_no_target_group(platform_list) platform_manager[name] = make_no_target_group(platform_list)
def _get_unavailable_platforms() -> dict[str, str]:
res = {}
for name, platform in platform_manager.items():
if platform.site.require_browser and not plugin_config.bison_use_browser:
res[name] = "需要启用 bison_use_browser"
return res
# platform => reason for not available
unavailable_paltforms: dict[str, str] = _get_unavailable_platforms()
+62 -1
View File
@@ -2,10 +2,24 @@ import sys
import asyncio import asyncio
import inspect import inspect
from enum import Enum from enum import Enum
from functools import wraps
from dataclasses import dataclass from dataclasses import dataclass
from collections.abc import Set as AbstractSet from collections.abc import Set as AbstractSet
from collections.abc import Callable, Sequence, Awaitable, AsyncGenerator from collections.abc import Callable, Sequence, Awaitable, AsyncGenerator
from typing import TYPE_CHECKING, Any, Generic, TypeVar, Protocol, TypeAlias, TypedDict, NamedTuple, runtime_checkable from typing import (
TYPE_CHECKING,
Any,
Generic,
TypeVar,
Protocol,
ParamSpec,
TypeAlias,
TypedDict,
NamedTuple,
Concatenate,
overload,
runtime_checkable,
)
from nonebot import logger from nonebot import logger
@@ -17,6 +31,7 @@ TAddon = TypeVar("TAddon", contravariant=True)
TState = TypeVar("TState", contravariant=True) TState = TypeVar("TState", contravariant=True)
TEvent = TypeVar("TEvent", contravariant=True) TEvent = TypeVar("TEvent", contravariant=True)
TFSM = TypeVar("TFSM", bound="FSM", contravariant=True) TFSM = TypeVar("TFSM", bound="FSM", contravariant=True)
P = ParamSpec("P")
class StateError(Exception): ... class StateError(Exception): ...
@@ -163,6 +178,52 @@ class FSM(Generic[TState, TEvent, TAddon]):
self.started = False self.started = False
del self.machine del self.machine
self.current_state = self.graph["initial"]
self.machine = self._core() self.machine = self._core()
logger.trace("FSM closed") logger.trace("FSM closed")
@overload
def reset_on_exception(
func: Callable[Concatenate[TFSM, P], Awaitable[ActionReturn]],
) -> Callable[Concatenate[TFSM, P], Awaitable[ActionReturn]]:
"""自动在发生异常后重置 FSM"""
@overload
def reset_on_exception(
auto_start: bool = False,
) -> Callable[
[Callable[Concatenate[TFSM, P], Awaitable[ActionReturn]]], Callable[Concatenate[TFSM, P], Awaitable[ActionReturn]]
]:
"""自动在异常后重置 FSM,当 auto_start 为 True 时,自动启动 FSM"""
# 参考自 dataclasses.dataclass 的实现
def reset_on_exception(func=None, /, *, auto_start=False): # pyright: ignore[reportInconsistentOverload]
def warp(func: Callable[Concatenate[TFSM, P], Awaitable[ActionReturn]]):
return __reset_clear_up(func, auto_start)
# 判断调用的是 @reset_on_exception 还是 @reset_on_exception(...)
if func is None:
# 调用的是带括号的
return warp
# 调用的是不带括号的
return warp(func)
def __reset_clear_up(func: Callable[Concatenate[TFSM, P], Awaitable[ActionReturn]], auto_start: bool):
@wraps(func)
async def wrapper(fsm_self: TFSM, *args: P.args, **kwargs: P.kwargs) -> ActionReturn:
try:
return await func(fsm_self, *args, **kwargs)
except Exception as e:
logger.error(f"Exception in {func.__name__}: {e}")
await fsm_self.reset()
if auto_start and not fsm_self.started:
await fsm_self.start()
raise e
return wrapper
+13 -4
View File
@@ -14,7 +14,7 @@ from httpx import URL as HttpxURL
from nonebot_bison.types import Target from nonebot_bison.types import Target
from .models import DynRawPost from .models import DynRawPost
from .fsm import FSM, Condition, StateGraph, Transition, ActionReturn from .fsm import FSM, Condition, StateGraph, Transition, ActionReturn, reset_on_exception
if TYPE_CHECKING: if TYPE_CHECKING:
from .platforms import Bilibili from .platforms import Bilibili
@@ -218,6 +218,11 @@ class RetryFSM(FSM[RetryState, RetryEvent, RetryAddon[TBilibili]]):
self.addon.reset_all() self.addon.reset_all()
await super().reset() await super().reset()
@override
@reset_on_exception
async def emit(self, event: RetryEvent):
await super().emit(event)
# FIXME: 拿出来是方便测试了,但全局单例会导致所有被装饰的函数共享状态,有待改进 # FIXME: 拿出来是方便测试了,但全局单例会导致所有被装饰的函数共享状态,有待改进
_retry_fsm = RetryFSM(RETRY_GRAPH, RetryAddon["Bilibili"]()) _retry_fsm = RetryFSM(RETRY_GRAPH, RetryAddon["Bilibili"]())
@@ -236,15 +241,19 @@ def retry_for_352(api_func: Callable[[TBilibili, Target], Awaitable[list[DynRawP
case RetryState.NROMAL | RetryState.REFRESH | RetryState.RAISE: case RetryState.NROMAL | RetryState.REFRESH | RetryState.RAISE:
try: try:
res = await api_func(bls, *args, **kwargs) res = await api_func(bls, *args, **kwargs)
except ApiCode352Error: except ApiCode352Error as e:
logger.error("API 352 错误") logger.warning("本次 Bilibili API 请求返回 352 错误")
await _retry_fsm.emit(RetryEvent.REQUEST_AND_RAISE) await _retry_fsm.emit(RetryEvent.REQUEST_AND_RAISE)
if _retry_fsm.current_state == RetryState.RAISE:
raise e
return [] return []
else: else:
await _retry_fsm.emit(RetryEvent.REQUEST_AND_SUCCESS) await _retry_fsm.emit(RetryEvent.REQUEST_AND_SUCCESS)
return res return res
case RetryState.BACKOFF: case RetryState.BACKOFF:
logger.warning("回避中,不请求") logger.warning("本次 Bilibili 请求回避中,不请求")
await _retry_fsm.emit(RetryEvent.IN_BACKOFF_TIME) await _retry_fsm.emit(RetryEvent.IN_BACKOFF_TIME)
return [] return []
case _: case _:
+1 -1
View File
@@ -68,7 +68,7 @@ class BilibiliClientManager(ClientManager):
class BilibiliSite(Site): class BilibiliSite(Site):
name = "bilibili.com" name = "bilibili.com"
schedule_setting = {"seconds": 50} schedule_setting = {"seconds": 60}
schedule_type = "interval" schedule_type = "interval"
client_mgr = BilibiliClientManager client_mgr = BilibiliClientManager
require_browser = True require_browser = True
+3 -3
View File
@@ -9,7 +9,7 @@ from bs4 import BeautifulSoup as bs
from ..post import Post from ..post import Post
from .platform import NewMessage from .platform import NewMessage
from ..types import Target, RawPost from ..types import Target, RawPost
from ..utils import Site, text_fletten, text_similarity from ..utils import Site, text_similarity
class RssSite(Site): class RssSite(Site):
@@ -32,7 +32,7 @@ class RssPost(Post):
for p in soup.find_all("p"): for p in soup.find_all("p"):
p.insert_after("\n") p.insert_after("\n")
return text_fletten(soup.get_text()) return soup.get_text()
class Rss(NewMessage): class Rss(NewMessage):
@@ -82,7 +82,7 @@ class Rss(NewMessage):
async def parse(self, raw_post: RawPost) -> Post: async def parse(self, raw_post: RawPost) -> Post:
title = raw_post.get("title", "") title = raw_post.get("title", "")
soup = bs(raw_post.description, "html.parser") soup = bs(raw_post.description, "html.parser")
desc = soup.text.strip() desc = raw_post.description
title, desc = self._text_process(title, desc) title, desc = self._text_process(title, desc)
pics = [x.attrs["src"] for x in soup("img")] pics = [x.attrs["src"] for x in soup("img")]
if raw_post.get("media_content"): if raw_post.get("media_content"):
+2 -1
View File
@@ -36,7 +36,8 @@ class PlugConfig(BaseModel):
bison_resend_times: int = 0 bison_resend_times: int = 0
bison_proxy: str | None = None bison_proxy: str | None = None
bison_ua: str = Field( bison_ua: str = Field(
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
" Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0",
description="默认UA", description="默认UA",
) )
bison_show_network_warning: bool = True bison_show_network_warning: bool = True
+3 -1
View File
@@ -9,9 +9,9 @@ from nonebot_plugin_saa import Text, PlatformTarget, SupportedAdapters
from ..types import Target from ..types import Target
from ..config import config from ..config import config
from ..apis import check_sub_target from ..apis import check_sub_target
from ..platform import Platform, platform_manager
from ..config.db_config import SubscribeDupException from ..config.db_config import SubscribeDupException
from .utils import common_platform, ensure_user_info, gen_handle_cancel from .utils import common_platform, ensure_user_info, gen_handle_cancel
from ..platform import Platform, platform_manager, unavailable_paltforms
def do_add_sub(add_sub: type[Matcher]): def do_add_sub(add_sub: type[Matcher]):
@@ -39,6 +39,8 @@ def do_add_sub(add_sub: type[Matcher]):
elif platform == "取消": elif platform == "取消":
await add_sub.finish("已中止订阅") await add_sub.finish("已中止订阅")
elif platform in platform_manager: elif platform in platform_manager:
if platform in unavailable_paltforms:
await add_sub.finish(f"无法订阅 {platform}{unavailable_paltforms[platform]}")
state["platform"] = platform state["platform"] = platform
else: else:
await add_sub.reject("平台输入错误") await add_sub.reject("平台输入错误")
+4 -4
View File
@@ -11,9 +11,9 @@
"docs:update-package": "pnpm dlx vp-update" "docs:update-package": "pnpm dlx vp-update"
}, },
"devDependencies": { "devDependencies": {
"@vuepress/bundler-vite": "2.0.0-rc.14", "@vuepress/bundler-vite": "2.0.0-rc.15",
"vue": "^3.4.31", "vue": "^3.5.6",
"vuepress": "2.0.0-rc.14", "vuepress": "2.0.0-rc.15",
"vuepress-theme-hope": "2.0.0-rc.50" "vuepress-theme-hope": "2.0.0-rc.52"
} }
} }
+2121 -1771
View File
File diff suppressed because it is too large Load Diff
Generated
+536 -519
View File
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "nonebot-bison" name = "nonebot-bison"
version = "0.9.3" version = "0.9.4"
description = "Subscribe message from social medias" description = "Subscribe message from social medias"
authors = ["felinae98 <felinae225@qq.com>"] authors = ["felinae98 <felinae225@qq.com>"]
license = "MIT" license = "MIT"
@@ -24,40 +24,40 @@ classifiers = [
python = ">=3.10,<4.0.0" python = ">=3.10,<4.0.0"
beautifulsoup4 = ">=4.12.3" beautifulsoup4 = ">=4.12.3"
feedparser = "^6.0.11" feedparser = "^6.0.11"
httpx = ">=0.27.0" httpx = ">=0.27.2"
nonebot2 = { extras = ["fastapi"], version = "^2.3.2" } nonebot2 = { extras = ["fastapi"], version = "^2.3.3" }
nonebot-adapter-onebot = "^2.4.4" nonebot-adapter-onebot = "^2.4.5"
nonebot-plugin-htmlrender = ">=0.3.3" nonebot-plugin-htmlrender = ">=0.3.5"
nonebot-plugin-datastore = ">=1.3.0,<2.0.0" nonebot-plugin-datastore = ">=1.3.0,<2.0.0"
nonebot-plugin-apscheduler = ">=0.5.0" nonebot-plugin-apscheduler = ">=0.5.0"
nonebot-plugin-send-anything-anywhere = ">=0.6.1,<0.7.0" nonebot-plugin-send-anything-anywhere = ">=0.7.1,<0.7.2"
pillow = ">=8.4.0,<11.0" pillow = ">=10.4.0,<11.0"
pyjwt = "^2.8.0" pyjwt = "^2.9.0"
python-socketio = "^5.11.3" python-socketio = "^5.11.4"
tinydb = "^4.8.0" tinydb = "^4.8.0"
qrcode = "^7.4.2" qrcode = "^7.4.2"
pydantic = ">=1.10.17,<3.0.0,!=2.5.0,!=2.5.1" pydantic = ">=2.9.2,<3.0.0,!=2.5.0,!=2.5.1"
lxml = ">=5.2.2" lxml = ">=5.3.0"
yarl = ">=1.9.4" yarl = ">=1.11.1"
hishel = "^0.0.20" hishel = "^0.0.30"
expiringdictx = "^1.0.1" expiringdictx = "^1.1.0"
rapidfuzz = "^3.9.3" rapidfuzz = "^3.9.7"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
black = ">=23.12.1,<25.0" black = ">=24.8.0,<25.0"
ipdb = "^0.13.13" ipdb = "^0.13.13"
isort = "^5.13.2" isort = "^5.13.2"
nonemoji = "^0.1.4" nonemoji = "^0.1.4"
nb-cli = "^1.4.1" nb-cli = "^1.4.2"
pre-commit = "^3.7.1" pre-commit = "^3.8.0"
ruff = "^0.6.0" ruff = "^0.6.5"
[tool.poetry.group.test.dependencies] [tool.poetry.group.test.dependencies]
flaky = "^3.8.1" flaky = "^3.8.1"
nonebug = "^0.3.7" nonebug = "^0.3.7"
nonebug-saa = "^0.4.1" nonebug-saa = "^0.4.1"
pytest = ">=7.4.4,<9.0.0" pytest = ">=8.3.3,<9.0.0"
pytest-asyncio = ">=0.23.7,<0.24.0" pytest-asyncio = ">=0.24.0,<0.24.1"
pytest-cov = ">=5.0.0,<6" pytest-cov = ">=5.0.0,<6"
pytest-mock = "^3.14.0" pytest-mock = "^3.14.0"
pytest-xdist = { extras = ["psutil"], version = "^3.6.1" } pytest-xdist = { extras = ["psutil"], version = "^3.6.1" }
@@ -68,10 +68,10 @@ freezegun = "^1.5.1"
optional = true optional = true
[tool.poetry.group.docker.dependencies] [tool.poetry.group.docker.dependencies]
nb-cli = "^1.4.1" nb-cli = "^1.4.2"
nonebot2 = { extras = ["fastapi", "aiohttp"], version = "^2.3.2" } nonebot2 = { extras = ["fastapi", "aiohttp"], version = "^2.3.3" }
nonebot-adapter-red = "^0.9.0" nonebot-adapter-red = "^0.9.0"
nonebot-adapter-qq = "^1.4.4" nonebot-adapter-qq = "^1.5.1"
poetry-core = "^1.9.0" poetry-core = "^1.9.0"
[tool.poetry.extras] [tool.poetry.extras]
+10
View File
@@ -18,6 +18,7 @@ def pytest_configure(config: pytest.Config) -> None:
"superusers": {"10001"}, "superusers": {"10001"},
"command_start": {""}, "command_start": {""},
"log_level": "TRACE", "log_level": "TRACE",
"bison_use_browser": True,
} }
@@ -113,3 +114,12 @@ async def use_legacy_config(app: App):
# 清除单例的缓存 # 清除单例的缓存
Singleton._instances.clear() Singleton._instances.clear()
@pytest.fixture
async def _no_browser(app: App, mocker: MockerFixture):
from nonebot_bison.plugin_config import plugin_config
from nonebot_bison.platform import _get_unavailable_platforms
mocker.patch.object(plugin_config, "bison_use_browser", False)
mocker.patch("nonebot_bison.platform.unavailable_paltforms", _get_unavailable_platforms())
+94 -1
View File
@@ -58,6 +58,92 @@ def without_dynamic(app: App):
) )
@pytest.mark.asyncio
async def test_reset_on_exception(app: App):
from strenum import StrEnum
from nonebot_bison.platform.bilibili.fsm import FSM, StateGraph, Transition, ActionReturn, reset_on_exception
class State(StrEnum):
A = "A"
B = "B"
C = "C"
class Event(StrEnum):
A = "A"
B = "B"
C = "C"
class Addon:
pass
async def raction(from_: State, event: Event, to: State, addon: Addon) -> ActionReturn:
logger.info(f"action: {from_} -> {to}")
raise RuntimeError("test")
async def action(from_: State, event: Event, to: State, addon: Addon) -> ActionReturn:
logger.info(f"action: {from_} -> {to}")
graph: StateGraph[State, Event, Addon] = {
"transitions": {
State.A: {
Event.A: Transition(raction, State.B),
Event.B: Transition(action, State.C),
},
State.B: {
Event.B: Transition(action, State.C),
},
State.C: {
Event.C: Transition(action, State.A),
},
},
"initial": State.A,
}
addon = Addon()
class AFSM(FSM[State, Event, Addon]):
@reset_on_exception(auto_start=True)
async def emit(self, event: Event):
return await super().emit(event)
fsm = AFSM(graph, addon)
await fsm.start()
with pytest.raises(RuntimeError):
await fsm.emit(Event.A)
assert fsm.started is True
await fsm.emit(Event.B)
await fsm.emit(Event.C)
class BFSM(FSM[State, Event, Addon]):
@reset_on_exception
async def emit(self, event: Event):
return await super().emit(event)
fsm = BFSM(graph, addon)
await fsm.start()
with pytest.raises(RuntimeError):
await fsm.emit(Event.A)
assert fsm.started is False
with pytest.raises(TypeError, match="can't send non-None value to a just-started async generator"):
await fsm.emit(Event.B)
class CFSM(FSM[State, Event, Addon]): ...
fsm = CFSM(graph, addon)
await fsm.start()
with pytest.raises(RuntimeError):
await fsm.emit(Event.A)
assert fsm.started is True
with pytest.raises(StopAsyncIteration):
await fsm.emit(Event.B)
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_retry_for_352(app: App, mocker: MockerFixture): async def test_retry_for_352(app: App, mocker: MockerFixture):
from nonebot_bison.post import Post from nonebot_bison.post import Post
@@ -183,7 +269,7 @@ async def test_retry_for_352(app: App, mocker: MockerFixture):
fakebili.set_raise352(True) fakebili.set_raise352(True)
for state in test_state_list: for state in test_state_list[:-3]:
logger.info(f"\n\nnow state should be {state}") logger.info(f"\n\nnow state should be {state}")
assert _retry_fsm.current_state == state assert _retry_fsm.current_state == state
@@ -194,6 +280,13 @@ async def test_retry_for_352(app: App, mocker: MockerFixture):
if state == RetryState.BACKOFF: if state == RetryState.BACKOFF:
freeze_start += timedelta_length * (_retry_fsm.addon.backoff_count + 1) ** 2 freeze_start += timedelta_length * (_retry_fsm.addon.backoff_count + 1) ** 2
for state in test_state_list[-3:]:
logger.info(f"\n\nnow state should be {state}")
assert _retry_fsm.current_state == state
with pytest.raises(ApiCode352Error):
await fakebili.get_sub_list(Target("t1")) # type: ignore
assert client_mgr.refresh_client_call_count == 4 * 3 + 3 # refresh + raise assert client_mgr.refresh_client_call_count == 4 * 3 + 3 # refresh + raise
assert client_mgr.get_client_call_count == 2 + 4 * 3 + 3 # previous + refresh + raise assert client_mgr.get_client_call_count == 2 + 4 * 3 + 3 # previous + refresh + raise
+18 -4
View File
@@ -88,9 +88,21 @@ async def test_fetch_new_1(
assert post1.title is None assert post1.title is None
assert ( assert (
post1.content post1.content
== "【#統合戦略】 引き続き新テーマ「ミヅキと紺碧の樹」の新要素及びシステムの変更点を一部ご紹介します!" == "【#統合戦略】 <br />引き続き新テーマ「ミヅキと紺碧の樹」の新要素及びシステムの変更点を一部ご紹介します! "
" 今回は「灯火」、「ダイス」、「記号認識」、「鍵」についてです。詳細は添付の画像をご確認ください。" "<br /><br />"
"#アークナイツ https://t.co/ARmptV0Zvu" "今回は「灯火」、「ダイス」、「記号認識」、「鍵」についてです。<br />詳細は添付の画像をご確認ください。"
"<br /><br />"
"#アークナイツ https://t.co/ARmptV0Zvu<br />"
'<img src="https://pbs.twimg.com/media/FwZG9YAacAIXDw2?format=jpg&amp;name=orig" />'
)
plain_content = await post1.get_plain_content()
assert (
plain_content == "【#統合戦略】 \n"
"引き続き新テーマ「ミヅキと紺碧の樹」の新要素及びシステムの変更点を一部ご紹介します! \n\n"
"今回は「灯火」、「ダイス」、「記号認識」、「鍵」についてです。\n"
"詳細は添付の画像をご確認ください。\n\n"
"#アークナイツ https://t.co/ARmptV0Zvu\n"
"[图片]"
) )
@@ -174,7 +186,9 @@ async def test_fetch_new_4(
assert len(res2[0][1]) == 1 assert len(res2[0][1]) == 1
post1 = res2[0][1][0] post1 = res2[0][1][0]
assert post1.url == "https://wallhaven.cc/w/85rjej" assert post1.url == "https://wallhaven.cc/w/85rjej"
assert post1.content == "85rjej.jpg" assert post1.content == '<img alt="loading" class="lazyload" src="https://th.wallhaven.cc/small/85/85rjej.jpg" />'
plain_content = await post1.get_plain_content()
assert plain_content == "[图片]"
def test_similar_text_process(): def test_similar_text_process():
+45
View File
@@ -615,3 +615,48 @@ async def test_add_with_bilibili_bangumi_target_parser(app: App, init_scheduler)
assert sub.tags == [] assert sub.tags == []
assert sub.target.platform_name == "bilibili-bangumi" assert sub.target.platform_name == "bilibili-bangumi"
assert sub.target.target_name == "汉化日记 第三季" assert sub.target.target_name == "汉化日记 第三季"
@pytest.mark.asyncio
async def test_subscribe_platform_requires_browser(app: App, mocker: MockerFixture):
from nonebot.adapters.onebot.v11.event import Sender
from nonebot.adapters.onebot.v11.message import Message
from nonebot_bison.plugin_config import plugin_config
from nonebot_bison.sub_manager import add_sub_matcher, common_platform
from nonebot_bison.platform import platform_manager, unavailable_paltforms
mocker.patch.object(plugin_config, "bison_use_browser", False)
mocker.patch.dict(unavailable_paltforms, {"bilibili": "需要启用 bison_use_browser"})
async with app.test_matcher(add_sub_matcher) as ctx:
bot = ctx.create_bot()
event_1 = fake_group_message_event(
message=Message("添加订阅"),
sender=Sender(card="", nickname="test", role="admin"),
to_me=True,
)
ctx.receive_event(bot, event_1)
ctx.should_pass_rule()
ctx.should_call_send(
event_1,
BotReply.add_reply_on_platform(platform_manager=platform_manager, common_platform=common_platform),
True,
)
event_2 = fake_group_message_event(
message=Message("全部"), sender=Sender(card="", nickname="test", role="admin")
)
ctx.receive_event(bot, event_2)
ctx.should_rejected()
ctx.should_call_send(
event_2,
BotReply.add_reply_on_platform_input_allplatform(platform_manager),
True,
)
event_3 = fake_group_message_event(message=Message("bilibili"), sender=fake_admin_user)
ctx.receive_event(bot, event_3)
ctx.should_call_send(
event_3,
BotReply.add_reply_platform_unavailable("bilibili", "需要启用 bison_use_browser"),
True,
)
+3 -2
View File
@@ -17,7 +17,8 @@ async def test_http_error(app: App):
assert ctx.gen_req_records() == [ assert ctx.gen_req_records() == [
"https://example.com Headers({'host': 'example.com', 'accept': '*/*', 'accept-encoding': 'gzip, deflate'," "https://example.com Headers({'host': 'example.com', 'accept': '*/*', 'accept-encoding': 'gzip, deflate',"
" 'connection': 'keep-alive', 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like" " 'connection': 'keep-alive', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
" Gecko) Chrome/51.0.2704.103 Safari/537.36'}) | [403] Headers({'content-length': '15', 'content-type':" " (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0'}) | [403] Headers({'content-length': '"
"15', 'content-type':"
' \'application/json\'}) {"error": "gg"}' ' \'application/json\'}) {"error": "gg"}'
] ]
+4
View File
@@ -146,6 +146,10 @@ class BotReply:
extra_text = ("1." + target_promot + "\n2.") if target_promot else "" extra_text = ("1." + target_promot + "\n2.") if target_promot else ""
return extra_text + base_text return extra_text + base_text
@staticmethod
def add_reply_platform_unavailable(platform: str, reason: str) -> str:
return f"无法订阅 {platform}{reason}"
add_reply_on_id_input_error = "id输入错误" add_reply_on_id_input_error = "id输入错误"
add_reply_on_target_parse_input_error = "不能从你的输入中提取出id,请检查你输入的内容是否符合预期" add_reply_on_target_parse_input_error = "不能从你的输入中提取出id,请检查你输入的内容是否符合预期"
add_reply_on_platform_input_error = "平台输入错误" add_reply_on_platform_input_error = "平台输入错误"