mirror of
				https://github.com/suyiiyii/nonebot-bison.git
				synced 2025-11-04 21:44:52 +08:00 
			
		
		
		
	Merge branch 'main' into feat/bilibili-cookie
This commit is contained in:
		
						commit
						672405255d
					
				@ -2,9 +2,9 @@
 | 
				
			|||||||
  "name": "Default Linux Universal",
 | 
					  "name": "Default Linux Universal",
 | 
				
			||||||
  "image": "mcr.microsoft.com/devcontainers/universal:2-linux",
 | 
					  "image": "mcr.microsoft.com/devcontainers/universal:2-linux",
 | 
				
			||||||
  "features": {
 | 
					  "features": {
 | 
				
			||||||
    "ghcr.io/devcontainers-contrib/features/poetry:2": {}
 | 
					    "ghcr.io/va-h/devcontainers-features/uv:1": {}
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "postCreateCommand": "poetry config virtualenvs.in-project true && poetry install -E all && poetry run pre-commit install && npm install -g pnpm && pnpm install",
 | 
					  "postCreateCommand": "uv venv && uv sync --all-groups --all-extras && uv run pre-commit install && npm install -g pnpm && pnpm install",
 | 
				
			||||||
  "customizations": {
 | 
					  "customizations": {
 | 
				
			||||||
    "vscode": {
 | 
					    "vscode": {
 | 
				
			||||||
      "settings": {
 | 
					      "settings": {
 | 
				
			||||||
@ -12,7 +12,7 @@
 | 
				
			|||||||
        "python.analysis.typeCheckingMode": "basic",
 | 
					        "python.analysis.typeCheckingMode": "basic",
 | 
				
			||||||
        "ruff.organizeImports": false,
 | 
					        "ruff.organizeImports": false,
 | 
				
			||||||
        "[python]": {
 | 
					        "[python]": {
 | 
				
			||||||
          "editor.defaultFormatter": "ms-python.black-formatter",
 | 
					          "editor.defaultFormatter": "charliermarsh.ruff",
 | 
				
			||||||
          "editor.codeActionsOnSave": {
 | 
					          "editor.codeActionsOnSave": {
 | 
				
			||||||
            "source.fixAll.ruff": true,
 | 
					            "source.fixAll.ruff": true,
 | 
				
			||||||
            "source.organizeImports": true
 | 
					            "source.organizeImports": true
 | 
				
			||||||
@ -44,8 +44,6 @@
 | 
				
			|||||||
      "extensions": [
 | 
					      "extensions": [
 | 
				
			||||||
        "ms-python.python",
 | 
					        "ms-python.python",
 | 
				
			||||||
        "ms-python.vscode-pylance",
 | 
					        "ms-python.vscode-pylance",
 | 
				
			||||||
        "ms-python.isort",
 | 
					 | 
				
			||||||
        "ms-python.black-formatter",
 | 
					 | 
				
			||||||
        "charliermarsh.ruff",
 | 
					        "charliermarsh.ruff",
 | 
				
			||||||
        "EditorConfig.EditorConfig",
 | 
					        "EditorConfig.EditorConfig",
 | 
				
			||||||
        "esbenp.prettier-vscode",
 | 
					        "esbenp.prettier-vscode",
 | 
				
			||||||
 | 
				
			|||||||
@ -1,19 +1,24 @@
 | 
				
			|||||||
*.ini
 | 
					*.ini
 | 
				
			||||||
*.yaml
 | 
					 | 
				
			||||||
*.yml
 | 
					*.yml
 | 
				
			||||||
*.md
 | 
					*.md
 | 
				
			||||||
*.json
 | 
					 | 
				
			||||||
*.toml
 | 
					 | 
				
			||||||
*.xml
 | 
					*.xml
 | 
				
			||||||
tests
 | 
					tests
 | 
				
			||||||
node_modules
 | 
					node_modules
 | 
				
			||||||
admin-frontend
 | 
					 | 
				
			||||||
data*
 | 
					data*
 | 
				
			||||||
htmlcov
 | 
					htmlcov
 | 
				
			||||||
docker
 | 
					docker
 | 
				
			||||||
dist
 | 
					dist
 | 
				
			||||||
docs
 | 
					docs
 | 
				
			||||||
.*
 | 
					venv
 | 
				
			||||||
 | 
					.venv
 | 
				
			||||||
 | 
					/admin-frontend/node_modules
 | 
				
			||||||
 | 
					/LICENSE
 | 
				
			||||||
 | 
					/.editorconfig
 | 
				
			||||||
 | 
					/.gitattributes
 | 
				
			||||||
 | 
					/.prettierignore
 | 
				
			||||||
 | 
					/.prettierrc
 | 
				
			||||||
 | 
					/.devcontainer/
 | 
				
			||||||
 | 
					/.github/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
!pyproject.toml
 | 
					# self install 时需要
 | 
				
			||||||
!README.md
 | 
					!README.md
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								.github/ISSUE_TEMPLATE/issue.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/ISSUE_TEMPLATE/issue.yml
									
									
									
									
										vendored
									
									
								
							@ -27,7 +27,7 @@ body:
 | 
				
			|||||||
      description: 请选择安装方式
 | 
					      description: 请选择安装方式
 | 
				
			||||||
      options:
 | 
					      options:
 | 
				
			||||||
        - 通过 nb-cli 安装
 | 
					        - 通过 nb-cli 安装
 | 
				
			||||||
        - 使用 poetry/pdm 等现代包管理器安装
 | 
					        - 使用 uv/poetry/pdm 等现代包管理器安装
 | 
				
			||||||
        - 通过 pip install 安装
 | 
					        - 通过 pip install 安装
 | 
				
			||||||
        - 克隆或下载项目直接使用
 | 
					        - 克隆或下载项目直接使用
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										26
									
								
								.github/actions/setup-python/action.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								.github/actions/setup-python/action.yml
									
									
									
									
										vendored
									
									
								
							@ -6,6 +6,14 @@ inputs:
 | 
				
			|||||||
    description: Python version
 | 
					    description: Python version
 | 
				
			||||||
    required: false
 | 
					    required: false
 | 
				
			||||||
    default: "3.10"
 | 
					    default: "3.10"
 | 
				
			||||||
 | 
					  install-deps:
 | 
				
			||||||
 | 
					    description: Install dependencies
 | 
				
			||||||
 | 
					    required: false
 | 
				
			||||||
 | 
					    default: "false"
 | 
				
			||||||
 | 
					  install-playwright:
 | 
				
			||||||
 | 
					    description: Install Playwright
 | 
				
			||||||
 | 
					    required: false
 | 
				
			||||||
 | 
					    default: "false"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
runs:
 | 
					runs:
 | 
				
			||||||
  using: "composite"
 | 
					  using: "composite"
 | 
				
			||||||
@ -14,7 +22,19 @@ runs:
 | 
				
			|||||||
      uses: actions/setup-python@v5
 | 
					      uses: actions/setup-python@v5
 | 
				
			||||||
      with:
 | 
					      with:
 | 
				
			||||||
        python-version: ${{ inputs.python-version }}
 | 
					        python-version: ${{ inputs.python-version }}
 | 
				
			||||||
    - name: Setup Poetry
 | 
					
 | 
				
			||||||
      uses: Gr1N/setup-poetry@v9
 | 
					    - name: Install the latest version of uv
 | 
				
			||||||
 | 
					      uses: astral-sh/setup-uv@v4
 | 
				
			||||||
      with:
 | 
					      with:
 | 
				
			||||||
        poetry-version: "1.7.1"
 | 
					        version: "latest"
 | 
				
			||||||
 | 
					        enable-cache: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - name: Install dependencies
 | 
				
			||||||
 | 
					      if: ${{ inputs.install-deps == 'true' }}
 | 
				
			||||||
 | 
					      run: uv sync --frozen
 | 
				
			||||||
 | 
					      shell: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - name: Install Playwright
 | 
				
			||||||
 | 
					      if: ${{ inputs.install-playwright == 'true' }}
 | 
				
			||||||
 | 
					      run: uv run playwright install
 | 
				
			||||||
 | 
					      shell: bash
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										42
									
								
								.github/workflows/main.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								.github/workflows/main.yml
									
									
									
									
										vendored
									
									
								
							@ -11,7 +11,7 @@ on:
 | 
				
			|||||||
      - nonebot_bison/**
 | 
					      - nonebot_bison/**
 | 
				
			||||||
      - tests/**
 | 
					      - tests/**
 | 
				
			||||||
      - pyproject.toml
 | 
					      - pyproject.toml
 | 
				
			||||||
      - poetry.lock
 | 
					      - uv.lock
 | 
				
			||||||
      - docker.env.prod
 | 
					      - docker.env.prod
 | 
				
			||||||
      - .github/**
 | 
					      - .github/**
 | 
				
			||||||
  pull_request:
 | 
					  pull_request:
 | 
				
			||||||
@ -21,7 +21,7 @@ on:
 | 
				
			|||||||
      - nonebot_bison/**
 | 
					      - nonebot_bison/**
 | 
				
			||||||
      - tests/**
 | 
					      - tests/**
 | 
				
			||||||
      - pyproject.toml
 | 
					      - pyproject.toml
 | 
				
			||||||
      - poetry.lock
 | 
					      - uv.lock
 | 
				
			||||||
      - docker.env.prod
 | 
					      - docker.env.prod
 | 
				
			||||||
      - .github/**
 | 
					      - .github/**
 | 
				
			||||||
    types:
 | 
					    types:
 | 
				
			||||||
@ -72,12 +72,11 @@ jobs:
 | 
				
			|||||||
        uses: ./.github/actions/setup-python
 | 
					        uses: ./.github/actions/setup-python
 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          python-version: ${{ matrix.python-version }}
 | 
					          python-version: ${{ matrix.python-version }}
 | 
				
			||||||
 | 
					          install-deps: "true"
 | 
				
			||||||
      - name: Install prerequisites
 | 
					          install-playwright: "true"
 | 
				
			||||||
        run: poetry install
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Run Pytest
 | 
					      - name: Run Pytest
 | 
				
			||||||
        run: poetry run pytest --cov-report xml --cov=./nonebot_bison -k 'not compare and not render' -n auto
 | 
					        run: uv run pytest --cov-report xml --cov=./nonebot_bison -k 'not compare and not render' -n auto
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Upload coverage report
 | 
					      - name: Upload coverage report
 | 
				
			||||||
        uses: codecov/codecov-action@v5
 | 
					        uses: codecov/codecov-action@v5
 | 
				
			||||||
@ -106,12 +105,11 @@ jobs:
 | 
				
			|||||||
        uses: ./.github/actions/setup-python
 | 
					        uses: ./.github/actions/setup-python
 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          python-version: ${{ matrix.python-version }}
 | 
					          python-version: ${{ matrix.python-version }}
 | 
				
			||||||
 | 
					          install-deps: "true"
 | 
				
			||||||
      - name: Install prerequisites
 | 
					          install-playwright: "true"
 | 
				
			||||||
        run: poetry install
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Run Pytest
 | 
					      - name: Run Pytest
 | 
				
			||||||
        run: poetry run pytest --cov-report xml --cov=./nonebot_bison -k 'not compare' -n auto
 | 
					        run: uv run pytest --cov-report xml --cov=./nonebot_bison -k 'not compare' -n auto
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Upload coverage report
 | 
					      - name: Upload coverage report
 | 
				
			||||||
        uses: codecov/codecov-action@v5
 | 
					        uses: codecov/codecov-action@v5
 | 
				
			||||||
@ -127,12 +125,6 @@ jobs:
 | 
				
			|||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - uses: actions/checkout@v4
 | 
					      - uses: actions/checkout@v4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Download frontend files
 | 
					 | 
				
			||||||
        uses: actions/download-artifact@v4
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          name: frontend
 | 
					 | 
				
			||||||
          path: ./nonebot_bison/admin_page/dist
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Set up QEMU
 | 
					      - name: Set up QEMU
 | 
				
			||||||
        uses: docker/setup-qemu-action@v3
 | 
					        uses: docker/setup-qemu-action@v3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -144,7 +136,7 @@ jobs:
 | 
				
			|||||||
        if: github.event_name == 'pull_request'
 | 
					        if: github.event_name == 'pull_request'
 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          context: .
 | 
					          context: .
 | 
				
			||||||
          file: ./docker/Dockerfile_with_frontend
 | 
					          file: ./docker/Dockerfile
 | 
				
			||||||
          push: false
 | 
					          push: false
 | 
				
			||||||
          load: true
 | 
					          load: true
 | 
				
			||||||
          tags: felinae98/nonebot-bison:dummy
 | 
					          tags: felinae98/nonebot-bison:dummy
 | 
				
			||||||
@ -174,26 +166,20 @@ jobs:
 | 
				
			|||||||
        if: github.event_name != 'pull_request'
 | 
					        if: github.event_name != 'pull_request'
 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          context: .
 | 
					          context: .
 | 
				
			||||||
          file: ./docker/Dockerfile_with_frontend
 | 
					          file: ./docker/Dockerfile
 | 
				
			||||||
          push: true
 | 
					          push: true
 | 
				
			||||||
          tags: felinae98/nonebot-bison:${{ env.GIT_BRANCH_NAME }}
 | 
					          tags: felinae98/nonebot-bison:${{ env.GIT_BRANCH_NAME }}
 | 
				
			||||||
          cache-from: type=gha
 | 
					          cache-from: type=gha
 | 
				
			||||||
          cache-to: type=gha,mode=max
 | 
					          cache-to: type=gha,mode=max
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  docker-main-sentry:
 | 
					  docker-main-nobrowser:
 | 
				
			||||||
    name: Docker main sentry
 | 
					    name: Docker main without browser
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
    needs: [build-frontend, test]
 | 
					    needs: [build-frontend, test]
 | 
				
			||||||
    if: github.event_name != 'pull_request'
 | 
					    if: github.event_name != 'pull_request'
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - uses: actions/checkout@v4
 | 
					      - uses: actions/checkout@v4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Download frontend files
 | 
					 | 
				
			||||||
        uses: actions/download-artifact@v4
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          name: frontend
 | 
					 | 
				
			||||||
          path: ./nonebot_bison/admin_page/dist
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Set up QEMU
 | 
					      - name: Set up QEMU
 | 
				
			||||||
        uses: docker/setup-qemu-action@v3
 | 
					        uses: docker/setup-qemu-action@v3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -215,8 +201,8 @@ jobs:
 | 
				
			|||||||
        uses: docker/build-push-action@v6
 | 
					        uses: docker/build-push-action@v6
 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          context: .
 | 
					          context: .
 | 
				
			||||||
          file: ./docker/Dockerfile_with_frontend_sentry
 | 
					          file: ./docker/Dockerfile_without_browser
 | 
				
			||||||
          push: ${{ github.event_name != 'pull_request' }}
 | 
					          push: ${{ github.event_name != 'pull_request' }}
 | 
				
			||||||
          tags: felinae98/nonebot-bison:${{ env.GIT_BRANCH_NAME }}-sentry
 | 
					          tags: felinae98/nonebot-bison:${{ env.GIT_BRANCH_NAME }}-nobrowser
 | 
				
			||||||
          cache-from: type=gha
 | 
					          cache-from: type=gha
 | 
				
			||||||
          cache-to: type=gha,mode=max
 | 
					          cache-to: type=gha,mode=max
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										40
									
								
								.github/workflows/manual-build.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								.github/workflows/manual-build.yaml
									
									
									
									
										vendored
									
									
								
							@ -9,35 +9,12 @@ on:
 | 
				
			|||||||
        type: string
 | 
					        type: string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jobs:
 | 
					jobs:
 | 
				
			||||||
  build-frontend:
 | 
					 | 
				
			||||||
    name: Build Frontend
 | 
					 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
      - uses: actions/checkout@v4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Build Frontend
 | 
					 | 
				
			||||||
        uses: ./.github/actions/build-frontend
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Upload dist
 | 
					 | 
				
			||||||
        uses: actions/upload-artifact@v4
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          name: frontend
 | 
					 | 
				
			||||||
          path: ./admin-frontend/build/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  docker-main:
 | 
					  docker-main:
 | 
				
			||||||
    name: Docker main
 | 
					    name: Docker main
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
    needs: [build-frontend]
 | 
					 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - uses: actions/checkout@v4
 | 
					      - uses: actions/checkout@v4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Download frontend files
 | 
					 | 
				
			||||||
        uses: actions/download-artifact@v4
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          name: frontend
 | 
					 | 
				
			||||||
          path: ./src/plugins/nonebot_bison/admin_page/dist
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Set up QEMU
 | 
					      - name: Set up QEMU
 | 
				
			||||||
        uses: docker/setup-qemu-action@v3
 | 
					        uses: docker/setup-qemu-action@v3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -54,25 +31,18 @@ jobs:
 | 
				
			|||||||
        uses: docker/build-push-action@v6
 | 
					        uses: docker/build-push-action@v6
 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          context: .
 | 
					          context: .
 | 
				
			||||||
          file: ./docker/Dockerfile_with_frontend
 | 
					          file: ./docker/Dockerfile
 | 
				
			||||||
          push: true
 | 
					          push: true
 | 
				
			||||||
          tags: felinae98/nonebot-bison:${{ inputs.dockerTag }}
 | 
					          tags: felinae98/nonebot-bison:${{ inputs.dockerTag }}
 | 
				
			||||||
          cache-from: type=gha
 | 
					          cache-from: type=gha
 | 
				
			||||||
          cache-to: type=gha,mode=max
 | 
					          cache-to: type=gha,mode=max
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  docker-main-sentry:
 | 
					  docker-main-nobrowser:
 | 
				
			||||||
    name: Docker main sentry
 | 
					    name: Docker main without browser
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
    needs: [build-frontend]
 | 
					 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - uses: actions/checkout@v4
 | 
					      - uses: actions/checkout@v4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Download frontend files
 | 
					 | 
				
			||||||
        uses: actions/download-artifact@v4
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          name: frontend
 | 
					 | 
				
			||||||
          path: ./src/plugins/nonebot_bison/admin_page/dist
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Set up QEMU
 | 
					      - name: Set up QEMU
 | 
				
			||||||
        uses: docker/setup-qemu-action@v3
 | 
					        uses: docker/setup-qemu-action@v3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -89,7 +59,7 @@ jobs:
 | 
				
			|||||||
        uses: docker/build-push-action@v6
 | 
					        uses: docker/build-push-action@v6
 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          context: .
 | 
					          context: .
 | 
				
			||||||
          file: ./docker/Dockerfile_with_frontend_sentry
 | 
					          file: ./docker/Dockerfile_without_browser
 | 
				
			||||||
          tags: felinae98/nonebot-bison:${{ inputs.dockerTag }}-sentry
 | 
					          tags: felinae98/nonebot-bison:${{ inputs.dockerTag }}-nobrowser
 | 
				
			||||||
          cache-from: type=gha
 | 
					          cache-from: type=gha
 | 
				
			||||||
          cache-to: type=gha,mode=max
 | 
					          cache-to: type=gha,mode=max
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8
									
								
								.github/workflows/pyd1-compat.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/pyd1-compat.yml
									
									
									
									
										vendored
									
									
								
							@ -11,7 +11,7 @@ on:
 | 
				
			|||||||
      - nonebot_bison/**
 | 
					      - nonebot_bison/**
 | 
				
			||||||
      - tests/**
 | 
					      - tests/**
 | 
				
			||||||
      - pyproject.toml
 | 
					      - pyproject.toml
 | 
				
			||||||
      - poetry.lock
 | 
					      - uv.lock
 | 
				
			||||||
      - docker.env.prod
 | 
					      - docker.env.prod
 | 
				
			||||||
      - .github/**
 | 
					      - .github/**
 | 
				
			||||||
  pull_request:
 | 
					  pull_request:
 | 
				
			||||||
@ -21,7 +21,7 @@ on:
 | 
				
			|||||||
      - nonebot_bison/**
 | 
					      - nonebot_bison/**
 | 
				
			||||||
      - tests/**
 | 
					      - tests/**
 | 
				
			||||||
      - pyproject.toml
 | 
					      - pyproject.toml
 | 
				
			||||||
      - poetry.lock
 | 
					      - uv.lock
 | 
				
			||||||
      - docker.env.prod
 | 
					      - docker.env.prod
 | 
				
			||||||
      - .github/**
 | 
					      - .github/**
 | 
				
			||||||
    types:
 | 
					    types:
 | 
				
			||||||
@ -55,7 +55,7 @@ jobs:
 | 
				
			|||||||
          python-version: ${{ matrix.python-version }}
 | 
					          python-version: ${{ matrix.python-version }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Install prerequisites
 | 
					      - name: Install prerequisites
 | 
				
			||||||
        run: poetry add pydantic@^1.10 && poetry install
 | 
					        run: uv add pydantic==1.10 && uv sync --frozen && uv run playwright install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Run Pytest
 | 
					      - name: Run Pytest
 | 
				
			||||||
        run: poetry run pytest -k 'not compare and not render' -n auto
 | 
					        run: uv run pytest -k 'not compare and not render' -n auto
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										4
									
								
								.github/workflows/release-trigger.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/release-trigger.yml
									
									
									
									
										vendored
									
									
								
							@ -16,7 +16,7 @@ jobs:
 | 
				
			|||||||
      - name: Setup Python environment
 | 
					      - name: Setup Python environment
 | 
				
			||||||
        uses: ./.github/actions/setup-python
 | 
					        uses: ./.github/actions/setup-python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - run: echo "TAG_NAME=v$(poetry version -s)" >> $GITHUB_ENV
 | 
					      - run: echo "TAG_NAME=v$(uvx --from=toml-cli toml get --toml-path=pyproject.toml project.version)" >> $GITHUB_ENV
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Archive Changelog
 | 
					      - name: Archive Changelog
 | 
				
			||||||
        uses: docker://ghcr.io/nonebot/auto-changelog:master
 | 
					        uses: docker://ghcr.io/nonebot/auto-changelog:master
 | 
				
			||||||
@ -30,6 +30,6 @@ jobs:
 | 
				
			|||||||
          git config user.name github-actions[bot]
 | 
					          git config user.name github-actions[bot]
 | 
				
			||||||
          git config user.email github-actions[bot]@users.noreply.github.com
 | 
					          git config user.email github-actions[bot]@users.noreply.github.com
 | 
				
			||||||
          git add .
 | 
					          git add .
 | 
				
			||||||
          git commit -m ":bookmark: Release $(poetry version -s)"
 | 
					          git commit -m ":bookmark: Release ${{ env.TAG_NAME }}"
 | 
				
			||||||
          git tag ${{ env.TAG_NAME }}
 | 
					          git tag ${{ env.TAG_NAME }}
 | 
				
			||||||
          git push && git push --tags
 | 
					          git push && git push --tags
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										17
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							@ -54,24 +54,17 @@ jobs:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      - name: Publish PyPI and Github
 | 
					      - name: Publish PyPI and Github
 | 
				
			||||||
        run: |
 | 
					        run: |
 | 
				
			||||||
          poetry publish --build -u ${{ secrets.PYPI_USERNAME }} -p ${{ secrets.PYPI_PASSWORD }} || echo "Already pushed to pypi"
 | 
					          uv publish --build -u ${{ secrets.PYPI_USERNAME }} -p ${{ secrets.PYPI_PASSWORD }} || echo "Already pushed to pypi"
 | 
				
			||||||
          gh release upload --clobber ${{ env.TAG_NAME }} dist/*
 | 
					          gh release upload --clobber ${{ env.TAG_NAME }} dist/*
 | 
				
			||||||
        env:
 | 
					        env:
 | 
				
			||||||
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 | 
					          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  publish-docker:
 | 
					  publish-docker:
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
    needs: build-frontend
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - uses: actions/checkout@v4
 | 
					      - uses: actions/checkout@v4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Download frontend files
 | 
					 | 
				
			||||||
        uses: actions/download-artifact@v4
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          name: frontend
 | 
					 | 
				
			||||||
          path: ./nonebot_bison/admin_page/dist
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Set up QEMU
 | 
					      - name: Set up QEMU
 | 
				
			||||||
        uses: docker/setup-qemu-action@v3
 | 
					        uses: docker/setup-qemu-action@v3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -92,7 +85,7 @@ jobs:
 | 
				
			|||||||
        uses: docker/build-push-action@v6
 | 
					        uses: docker/build-push-action@v6
 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          context: .
 | 
					          context: .
 | 
				
			||||||
          file: ./docker/Dockerfile_with_frontend
 | 
					          file: ./docker/Dockerfile
 | 
				
			||||||
          push: true
 | 
					          push: true
 | 
				
			||||||
          tags: |
 | 
					          tags: |
 | 
				
			||||||
            felinae98/nonebot-bison:latest
 | 
					            felinae98/nonebot-bison:latest
 | 
				
			||||||
@ -104,10 +97,10 @@ jobs:
 | 
				
			|||||||
        uses: docker/build-push-action@v6
 | 
					        uses: docker/build-push-action@v6
 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          context: .
 | 
					          context: .
 | 
				
			||||||
          file: ./docker/Dockerfile_with_frontend_sentry
 | 
					          file: ./docker/Dockerfile_without_browser
 | 
				
			||||||
          push: true
 | 
					          push: true
 | 
				
			||||||
          tags: |
 | 
					          tags: |
 | 
				
			||||||
            felinae98/nonebot-bison:${{ env.TAG_NAME }}-sentry
 | 
					            felinae98/nonebot-bison:${{ env.TAG_NAME }}-nobrowser
 | 
				
			||||||
            felinae98/nonebot-bison:sentry
 | 
					            felinae98/nonebot-bison:nobrowser
 | 
				
			||||||
          cache-from: type=gha
 | 
					          cache-from: type=gha
 | 
				
			||||||
          cache-to: type=gha,mode=max
 | 
					          cache-to: type=gha,mode=max
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								.github/workflows/ruff.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/ruff.yml
									
									
									
									
										vendored
									
									
								
							@ -19,7 +19,7 @@ jobs:
 | 
				
			|||||||
      - uses: actions/checkout@v4
 | 
					      - uses: actions/checkout@v4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Run Ruff Lint
 | 
					      - name: Run Ruff Lint
 | 
				
			||||||
        uses: astral-sh/ruff-action@v2
 | 
					        uses: astral-sh/ruff-action@v3
 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          src: >-
 | 
					          src: >-
 | 
				
			||||||
            nonebot_bison/
 | 
					            nonebot_bison/
 | 
				
			||||||
 | 
				
			|||||||
@ -1,16 +1,207 @@
 | 
				
			|||||||
FROM node:22.11.0 AS frontend
 | 
					# syntax=docker/dockerfile:1.10
 | 
				
			||||||
ADD . /app
 | 
					FROM python:3.12-slim AS metadata-stage
 | 
				
			||||||
WORKDIR /app/admin-frontend
 | 
					
 | 
				
			||||||
RUN npm install -g pnpm
 | 
					WORKDIR /tmp
 | 
				
			||||||
RUN pnpm install && pnpm build
 | 
					
 | 
				
			||||||
 | 
					ENV DEBIAN_FRONTEND=noninteractive \
 | 
				
			||||||
 | 
					    PYTHONUNBUFFERED=1 \
 | 
				
			||||||
 | 
					    TZ=Asia/Shanghai
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apt-get update && \
 | 
				
			||||||
 | 
					    apt-get install -y --no-install-recommends \
 | 
				
			||||||
 | 
					    curl \
 | 
				
			||||||
 | 
					    python3-pip \
 | 
				
			||||||
 | 
					    git \
 | 
				
			||||||
 | 
					    && pip install toml \
 | 
				
			||||||
 | 
					    && apt-get clean \
 | 
				
			||||||
 | 
					    && rm -rf /var/lib/apt/lists/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COPY ./pyproject.toml ./
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN echo "📋 Collecting metadata..." && \
 | 
				
			||||||
 | 
					    export CREATED_DATE="$(date -u '+%Y-%m-%d %H:%M:%S UTC')" && \
 | 
				
			||||||
 | 
					    export PYPROJECT_NAME=$(python3 -c 'import toml; print(toml.load("pyproject.toml")["project"]["name"])') && \
 | 
				
			||||||
 | 
					    export DESCRIPTION=$(python3 -c 'import toml; print(toml.load("pyproject.toml")["project"]["description"])') && \
 | 
				
			||||||
 | 
					    export AUTHOR=$(python3 -c 'import toml; print(toml.load("pyproject.toml")["project"]["authors"][0]["name"])') && \
 | 
				
			||||||
 | 
					    echo "⏰ Created Date: $CREATED_DATE" && \
 | 
				
			||||||
 | 
					    echo "📝 Project Name: $PYPROJECT_NAME" && \
 | 
				
			||||||
 | 
					    echo "📄 Description: $DESCRIPTION" && \
 | 
				
			||||||
 | 
					    echo "👤 Author: $AUTHOR" && \
 | 
				
			||||||
 | 
					    echo "$CREATED_DATE" > /tmp/CREATED_DATE && \
 | 
				
			||||||
 | 
					    echo "$PYPROJECT_NAME" > /tmp/PYPROJECT_NAME && \
 | 
				
			||||||
 | 
					    echo "$DESCRIPTION" > /tmp/DESCRIPTION && \
 | 
				
			||||||
 | 
					    echo "$AUTHOR" > /tmp/AUTHOR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN --mount=type=bind,source=./.git/,target=/tmp/.git/ \
 | 
				
			||||||
 | 
					    echo "🏷️  Checking version information..." && \
 | 
				
			||||||
 | 
					    VERSION=$(git describe --tags --exact-match 2>/dev/null || git rev-parse --short HEAD || echo "unknown") && \
 | 
				
			||||||
 | 
					    echo "📌 Version: $VERSION" && \
 | 
				
			||||||
 | 
					    echo "$VERSION" > /tmp/VERSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LABEL org.opencontainers.image.created="$(cat /tmp/CREATED_DATE)" \
 | 
				
			||||||
 | 
					      org.opencontainers.image.authors="$(cat /tmp/AUTHOR)" \
 | 
				
			||||||
 | 
					      org.opencontainers.image.description="$(cat /tmp/DESCRIPTION)" \
 | 
				
			||||||
 | 
					      org.opencontainers.image.name="$(cat /tmp/PYPROJECT_NAME)" \
 | 
				
			||||||
 | 
					      org.opencontainers.image.version="$(cat /tmp/VERSION)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM node:20-slim AS frontend-stage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WORKDIR /tmp/admin-frontend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENV TZ=Asia/Shanghai \
 | 
				
			||||||
 | 
					    PNPM_HOME="/pnpm" \
 | 
				
			||||||
 | 
					    PATH="$PNPM_HOME:$PATH"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COPY ./admin-frontend/package.json ./admin-frontend/pnpm-lock.yaml ./
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN corepack enable && \
 | 
				
			||||||
 | 
					    corepack prepare pnpm@latest --activate && \
 | 
				
			||||||
 | 
					    echo "🔔 Verifying Node.js installation..." && \
 | 
				
			||||||
 | 
					    if NODE_VERSION=$(node --version 2>&1); then \
 | 
				
			||||||
 | 
					        echo "✅ Node.js version ${NODE_VERSION} installed successfully"; \
 | 
				
			||||||
 | 
					    else \
 | 
				
			||||||
 | 
					        echo "❌ Node.js installation failed" && exit 1; \
 | 
				
			||||||
 | 
					    fi && \
 | 
				
			||||||
 | 
					    echo "🔔 Verifying pnpm installation..." && \
 | 
				
			||||||
 | 
					    if PNPM_VERSION=$(pnpm --version 2>&1); then \
 | 
				
			||||||
 | 
					        echo "✅ pnpm version ${PNPM_VERSION} installed successfully"; \
 | 
				
			||||||
 | 
					    else \
 | 
				
			||||||
 | 
					        echo "❌ pnpm installation failed" && exit 1; \
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN pnpm install --frozen-lockfile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COPY ./admin-frontend .
 | 
				
			||||||
 | 
					RUN mkdir -p ../nonebot_bison/admin_page/dist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN echo "🏗️ Starting frontend build..." && \
 | 
				
			||||||
 | 
					    pnpm run build && \
 | 
				
			||||||
 | 
					    echo "✅ Frontend build completed"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS playwright-stage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WORKDIR /tmp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENV DEBIAN_FRONTEND=noninteractive \
 | 
				
			||||||
 | 
					    PYTHONUNBUFFERED=1 \
 | 
				
			||||||
 | 
					    TZ=Asia/Shanghai
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN echo "📦 Installing playwright..." && \
 | 
				
			||||||
 | 
					    uvx playwright install --with-deps chromium && \
 | 
				
			||||||
 | 
					    echo "✅ Playwright installed successfully"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS uv-stage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FROM python:3.11
 | 
					 | 
				
			||||||
RUN python3 -m pip install poetry && poetry config virtualenvs.create false
 | 
					 | 
				
			||||||
WORKDIR /app
 | 
					WORKDIR /app
 | 
				
			||||||
COPY ./README.md ./pyproject.toml ./poetry.lock* /app/
 | 
					
 | 
				
			||||||
RUN poetry install --only=main,docker
 | 
					ENV DEBIAN_FRONTEND=noninteractive \
 | 
				
			||||||
ADD src /app/src
 | 
					    PYTHONUNBUFFERED=1 \
 | 
				
			||||||
ADD bot.py /app/
 | 
					    UV_COMPILE_BYTECODE=1 \
 | 
				
			||||||
COPY --from=frontend /app/nonebot_bison/admin_page/dist /app/nonebot_bison/admin_page/dist
 | 
					    UV_FROZEN=1 \
 | 
				
			||||||
ENV HOST=0.0.0.0
 | 
					    UV_LINK_MODE=copy \
 | 
				
			||||||
CMD ["nb", "run"]
 | 
					    TZ=Asia/Shanghai
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN echo "🔔 Verifying uv installation..." && \
 | 
				
			||||||
 | 
					    if UV_VERSION=$(uv --version 2>&1); then \
 | 
				
			||||||
 | 
					        echo "✅ uv version ${UV_VERSION} installed successfully"; \
 | 
				
			||||||
 | 
					    else \
 | 
				
			||||||
 | 
					        echo "❌ uv installation failed" && exit 1; \
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN --mount=type=cache,target=/root/.cache/uv \
 | 
				
			||||||
 | 
					    --mount=type=bind,source=uv.lock,target=uv.lock \
 | 
				
			||||||
 | 
					    --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
 | 
				
			||||||
 | 
					    echo "📦 Installing project dependencies..." && \
 | 
				
			||||||
 | 
					    uv sync --no-install-project --no-dev --extra docker && \
 | 
				
			||||||
 | 
					    echo "✅ Dependencies installed successfully"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS production
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WORKDIR /app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENV DEBIAN_FRONTEND=noninteractive \
 | 
				
			||||||
 | 
					    PYTHONUNBUFFERED=1 \
 | 
				
			||||||
 | 
					    UV_COMPILE_BYTECODE=1 \
 | 
				
			||||||
 | 
					    UV_FROZEN=1 \
 | 
				
			||||||
 | 
					    UV_LINK_MODE=copy \
 | 
				
			||||||
 | 
					    TZ=Asia/Shanghai \
 | 
				
			||||||
 | 
					    SHELL="/bin/bash"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN echo "📦 Installing system dependencies..." && \
 | 
				
			||||||
 | 
					    apt-get update && \
 | 
				
			||||||
 | 
					    apt-get install -y --no-install-recommends \
 | 
				
			||||||
 | 
					        curl \
 | 
				
			||||||
 | 
					        xvfb \
 | 
				
			||||||
 | 
					        fonts-noto-color-emoji \
 | 
				
			||||||
 | 
					        fonts-unifont \
 | 
				
			||||||
 | 
					        libfontconfig1 \
 | 
				
			||||||
 | 
					        libfreetype6 \
 | 
				
			||||||
 | 
					        xfonts-scalable \
 | 
				
			||||||
 | 
					        fonts-liberation \
 | 
				
			||||||
 | 
					        fonts-ipafont-gothic \
 | 
				
			||||||
 | 
					        fonts-wqy-zenhei \
 | 
				
			||||||
 | 
					        fonts-tlwg-loma-otf \
 | 
				
			||||||
 | 
					        at-spi2-common \
 | 
				
			||||||
 | 
					        fonts-freefont-ttf \
 | 
				
			||||||
 | 
					        libasound2 \
 | 
				
			||||||
 | 
					        libasound2-data \
 | 
				
			||||||
 | 
					        libatk-bridge2.0-0 \
 | 
				
			||||||
 | 
					        libatk1.0-0 \
 | 
				
			||||||
 | 
					        libatspi2.0-0 \
 | 
				
			||||||
 | 
					        libavahi-client3 \
 | 
				
			||||||
 | 
					        libavahi-common-data \
 | 
				
			||||||
 | 
					        libavahi-common3 \
 | 
				
			||||||
 | 
					        libcairo2 \
 | 
				
			||||||
 | 
					        libcups2 \
 | 
				
			||||||
 | 
					        libdatrie1 \
 | 
				
			||||||
 | 
					        libdbus-1-3 \
 | 
				
			||||||
 | 
					        libfribidi0 \
 | 
				
			||||||
 | 
					        libgbm1 \
 | 
				
			||||||
 | 
					        libglib2.0-0 \
 | 
				
			||||||
 | 
					        libgraphite2-3 \
 | 
				
			||||||
 | 
					        libharfbuzz0b \
 | 
				
			||||||
 | 
					        libnspr4 \
 | 
				
			||||||
 | 
					        libnss3 \
 | 
				
			||||||
 | 
					        libpango-1.0-0 \
 | 
				
			||||||
 | 
					        libthai-data \
 | 
				
			||||||
 | 
					        libthai0 \
 | 
				
			||||||
 | 
					        libwayland-server0 \
 | 
				
			||||||
 | 
					        libxcb-render0 \
 | 
				
			||||||
 | 
					        libxcomposite1 \
 | 
				
			||||||
 | 
					        libxdamage1 \
 | 
				
			||||||
 | 
					        libxi6 \
 | 
				
			||||||
 | 
					        libxkbcommon0 && \
 | 
				
			||||||
 | 
					    fc-cache -fv && \
 | 
				
			||||||
 | 
					    apt-get clean && \
 | 
				
			||||||
 | 
					    rm -rf /var/lib/apt/lists/* && \
 | 
				
			||||||
 | 
					    echo "✅ System dependencies installed successfully"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 少变动的放上面,频繁变动的放下面
 | 
				
			||||||
 | 
					COPY ./docker.env.prod ./.env
 | 
				
			||||||
 | 
					COPY --from=playwright-stage /root/.cache/ms-playwright /root/.cache/ms-playwright
 | 
				
			||||||
 | 
					COPY extra_plugins/ /app/extra_plugins/
 | 
				
			||||||
 | 
					COPY --from=frontend-stage /tmp/nonebot_bison/admin_page/dist ./nonebot_bison/admin_page/dist
 | 
				
			||||||
 | 
					COPY --from=uv-stage /app /app
 | 
				
			||||||
 | 
					COPY ./pyproject.toml ./uv.lock ./README.md ./
 | 
				
			||||||
 | 
					COPY nonebot_bison/ /app/nonebot_bison/
 | 
				
			||||||
 | 
					COPY --from=metadata-stage /tmp/VERSION /app/VERSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN --mount=type=cache,target=/root/.cache/uv \
 | 
				
			||||||
 | 
					    echo "📦 Installing bison project..." && \
 | 
				
			||||||
 | 
					    uv sync --no-dev --extra docker && \
 | 
				
			||||||
 | 
					    uv run nb adapter install nonebot-adapter-satori && \
 | 
				
			||||||
 | 
					    uv run nb adapter install nonebot-adapter-qq && \
 | 
				
			||||||
 | 
					    uv run nb plugin install nonebot-plugin-sentry && \
 | 
				
			||||||
 | 
					    echo "✅ Bison installed successfully"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPOSE 8080
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN echo '#!/bin/bash' > /app/start.sh && \
 | 
				
			||||||
 | 
					    echo 'echo "📌 Current bison Version: $(cat /app/VERSION)"' >> /app/start.sh && \
 | 
				
			||||||
 | 
					    echo 'echo "🚀 Starting service..."' >> /app/start.sh && \
 | 
				
			||||||
 | 
					    echo 'source /app/.venv/bin/activate' >> /app/start.sh && \
 | 
				
			||||||
 | 
					    echo 'nb run' >> /app/start.sh && \
 | 
				
			||||||
 | 
					    chmod +x /app/start.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CMD ["/app/start.sh"]
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +0,0 @@
 | 
				
			|||||||
FROM python:3.11
 | 
					 | 
				
			||||||
RUN   apt-get update && apt-get install -y fonts-wqy-microhei chromium nano
 | 
					 | 
				
			||||||
RUN python3 -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple
 | 
					 | 
				
			||||||
RUN python3 -m pip install poetry && poetry config virtualenvs.create false
 | 
					 | 
				
			||||||
WORKDIR /app
 | 
					 | 
				
			||||||
COPY ./README.md ./pyproject.toml ./poetry.lock* /app/
 | 
					 | 
				
			||||||
RUN poetry install --only=main,docker
 | 
					 | 
				
			||||||
ENV BISON_BROWSER=local:/usr/bin/chromium
 | 
					 | 
				
			||||||
ADD src /app/src
 | 
					 | 
				
			||||||
ENV HOST=0.0.0.0
 | 
					 | 
				
			||||||
@ -1,9 +0,0 @@
 | 
				
			|||||||
FROM python:3.11
 | 
					 | 
				
			||||||
RUN python3 -m pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
 | 
					 | 
				
			||||||
RUN python3 -m pip install poetry && poetry config virtualenvs.create false
 | 
					 | 
				
			||||||
WORKDIR /app
 | 
					 | 
				
			||||||
COPY ./README.md ./pyproject.toml ./poetry.lock* /app/
 | 
					 | 
				
			||||||
RUN poetry install --only=main,docker
 | 
					 | 
				
			||||||
ADD src /app/src
 | 
					 | 
				
			||||||
ENV HOST=0.0.0.0
 | 
					 | 
				
			||||||
CMD ["nb", "run"]
 | 
					 | 
				
			||||||
@ -1,49 +0,0 @@
 | 
				
			|||||||
# syntax=docker/dockerfile:1.10
 | 
					 | 
				
			||||||
FROM python:3.11-slim-bullseye AS base
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FROM base AS builder
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ENV PYTHONFAULTHANDLER=1 \
 | 
					 | 
				
			||||||
  PYTHONUNBUFFERED=1 \
 | 
					 | 
				
			||||||
  PYTHONHASHSEED=random \
 | 
					 | 
				
			||||||
  PIP_NO_CACHE_DIR=off \
 | 
					 | 
				
			||||||
  PIP_DISABLE_PIP_VERSION_CHECK=on \
 | 
					 | 
				
			||||||
  PIP_DEFAULT_TIMEOUT=100 \
 | 
					 | 
				
			||||||
  POETRY_NO_INTERACTION=1 \
 | 
					 | 
				
			||||||
  POETRY_VIRTUALENVS_CREATE=false \
 | 
					 | 
				
			||||||
  PATH="$PATH:/runtime/bin" \
 | 
					 | 
				
			||||||
  # Versions:
 | 
					 | 
				
			||||||
  POETRY_VERSION=1.7.1
 | 
					 | 
				
			||||||
RUN apt-get update && apt-get install -y build-essential unzip wget python-dev git
 | 
					 | 
				
			||||||
RUN pip install "poetry==$POETRY_VERSION"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
WORKDIR /src
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
COPY README.md pyproject.toml poetry.lock /src/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RUN poetry export --only=main,docker --without-hashes --no-interaction --no-ansi -f requirements.txt -o requirements.txt
 | 
					 | 
				
			||||||
RUN pip install --prefix=/runtime --force-reinstall -r requirements.txt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FROM base AS runtime
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
WORKDIR /app
 | 
					 | 
				
			||||||
RUN --mount=type=cache,target=/var/cache/apt \
 | 
					 | 
				
			||||||
  --mount=type=cache,target=/var/lib/apt \
 | 
					 | 
				
			||||||
    apt-get update && apt-get install -y xvfb fonts-noto-color-emoji ttf-unifont \
 | 
					 | 
				
			||||||
    libfontconfig1 libfreetype6 xfonts-cyrillic xfonts-scalable fonts-liberation \
 | 
					 | 
				
			||||||
    fonts-ipafont-gothic fonts-wqy-zenhei fonts-tlwg-loma-otf  \
 | 
					 | 
				
			||||||
    fonts-liberation libasound2 libatk-bridge2.0-0 libatk1.0-0 libatspi2.0-0 \
 | 
					 | 
				
			||||||
    libcairo2 libcups2 libdbus-1-3 libdrm2 libegl1 libgbm1 libglib2.0-0 libgtk-3-0 \
 | 
					 | 
				
			||||||
    libnspr4 libnss3 libpango-1.0-0 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 \
 | 
					 | 
				
			||||||
    libxdamage1 libxext6 libxfixes3 libxrandr2 libxshmfence1 nano
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
COPY --from=builder /runtime /usr/local
 | 
					 | 
				
			||||||
ADD . /app/
 | 
					 | 
				
			||||||
RUN pip install -e . && playwright install chromium
 | 
					 | 
				
			||||||
RUN mv docker.env.prod .env.prod && \
 | 
					 | 
				
			||||||
    nb adapter install nonebot-adapter-red && \
 | 
					 | 
				
			||||||
    nb adapter install nonebot-adapter-qq
 | 
					 | 
				
			||||||
ENV HOST=0.0.0.0
 | 
					 | 
				
			||||||
CMD ["nb", "run"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# vim: ft=dockerfile
 | 
					 | 
				
			||||||
@ -1,50 +0,0 @@
 | 
				
			|||||||
# syntax=docker/dockerfile:1.10
 | 
					 | 
				
			||||||
FROM python:3.11-slim-bullseye AS base
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FROM base AS builder
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ENV PYTHONFAULTHANDLER=1 \
 | 
					 | 
				
			||||||
  PYTHONUNBUFFERED=1 \
 | 
					 | 
				
			||||||
  PYTHONHASHSEED=random \
 | 
					 | 
				
			||||||
  PIP_NO_CACHE_DIR=off \
 | 
					 | 
				
			||||||
  PIP_DISABLE_PIP_VERSION_CHECK=on \
 | 
					 | 
				
			||||||
  PIP_DEFAULT_TIMEOUT=100 \
 | 
					 | 
				
			||||||
  POETRY_NO_INTERACTION=1 \
 | 
					 | 
				
			||||||
  POETRY_VIRTUALENVS_CREATE=false \
 | 
					 | 
				
			||||||
  PATH="$PATH:/runtime/bin" \
 | 
					 | 
				
			||||||
  # Versions:
 | 
					 | 
				
			||||||
  POETRY_VERSION=1.7.1
 | 
					 | 
				
			||||||
RUN apt-get update && apt-get install -y build-essential unzip wget python3-dev git
 | 
					 | 
				
			||||||
RUN pip install "poetry==$POETRY_VERSION"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
WORKDIR /src
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
COPY pyproject.toml poetry.lock /src/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RUN poetry export --only=main,docker --without-hashes --no-interaction --no-ansi -f requirements.txt -o requirements.txt
 | 
					 | 
				
			||||||
RUN pip install --prefix=/runtime --force-reinstall -r requirements.txt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FROM base AS runtime
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
WORKDIR /app
 | 
					 | 
				
			||||||
RUN --mount=type=cache,target=/var/cache/apt \
 | 
					 | 
				
			||||||
  --mount=type=cache,target=/var/lib/apt \
 | 
					 | 
				
			||||||
    apt-get update && apt-get install -y xvfb fonts-noto-color-emoji ttf-unifont \
 | 
					 | 
				
			||||||
    libfontconfig1 libfreetype6 xfonts-cyrillic xfonts-scalable fonts-liberation \
 | 
					 | 
				
			||||||
    fonts-ipafont-gothic fonts-wqy-zenhei fonts-tlwg-loma-otf  \
 | 
					 | 
				
			||||||
    fonts-liberation libasound2 libatk-bridge2.0-0 libatk1.0-0 libatspi2.0-0 \
 | 
					 | 
				
			||||||
    libcairo2 libcups2 libdbus-1-3 libdrm2 libegl1 libgbm1 libglib2.0-0 libgtk-3-0 \
 | 
					 | 
				
			||||||
    libnspr4 libnss3 libpango-1.0-0 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 \
 | 
					 | 
				
			||||||
    libxdamage1 libxext6 libxfixes3 libxrandr2 libxshmfence1 nano
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
COPY --from=builder /runtime /usr/local
 | 
					 | 
				
			||||||
ADD . /app/
 | 
					 | 
				
			||||||
RUN pip install -e . && playwright install chromium
 | 
					 | 
				
			||||||
RUN mv docker.env.prod .env.prod && \
 | 
					 | 
				
			||||||
    nb adapter install nonebot-adapter-red && \
 | 
					 | 
				
			||||||
    nb adapter install nonebot-adapter-qq && \
 | 
					 | 
				
			||||||
    nb plugin install nonebot-plugin-sentry
 | 
					 | 
				
			||||||
ENV HOST=0.0.0.0
 | 
					 | 
				
			||||||
CMD ["nb", "run"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# vim: ft=dockerfile
 | 
					 | 
				
			||||||
							
								
								
									
										147
									
								
								docker/Dockerfile_without_browser
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								docker/Dockerfile_without_browser
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,147 @@
 | 
				
			|||||||
 | 
					# syntax=docker/dockerfile:1.10
 | 
				
			||||||
 | 
					FROM python:3.12-slim AS metadata-stage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WORKDIR /tmp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENV DEBIAN_FRONTEND=noninteractive \
 | 
				
			||||||
 | 
					    PYTHONUNBUFFERED=1 \
 | 
				
			||||||
 | 
					    TZ=Asia/Shanghai
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apt-get update && \
 | 
				
			||||||
 | 
					    apt-get install -y --no-install-recommends \
 | 
				
			||||||
 | 
					    curl \
 | 
				
			||||||
 | 
					    python3-pip \
 | 
				
			||||||
 | 
					    git \
 | 
				
			||||||
 | 
					    && pip install toml \
 | 
				
			||||||
 | 
					    && apt-get clean \
 | 
				
			||||||
 | 
					    && rm -rf /var/lib/apt/lists/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COPY ./pyproject.toml ./
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN echo "📋 Collecting metadata..." && \
 | 
				
			||||||
 | 
					    export CREATED_DATE="$(date -u '+%Y-%m-%d %H:%M:%S UTC')" && \
 | 
				
			||||||
 | 
					    export PYPROJECT_NAME=$(python3 -c 'import toml; print(toml.load("pyproject.toml")["project"]["name"])') && \
 | 
				
			||||||
 | 
					    export DESCRIPTION=$(python3 -c 'import toml; print(toml.load("pyproject.toml")["project"]["description"])') && \
 | 
				
			||||||
 | 
					    export AUTHOR=$(python3 -c 'import toml; print(toml.load("pyproject.toml")["project"]["authors"][0]["name"])') && \
 | 
				
			||||||
 | 
					    echo "⏰ Created Date: $CREATED_DATE" && \
 | 
				
			||||||
 | 
					    echo "📝 Project Name: $PYPROJECT_NAME" && \
 | 
				
			||||||
 | 
					    echo "📄 Description: $DESCRIPTION" && \
 | 
				
			||||||
 | 
					    echo "👤 Author: $AUTHOR" && \
 | 
				
			||||||
 | 
					    echo "$CREATED_DATE" > /tmp/CREATED_DATE && \
 | 
				
			||||||
 | 
					    echo "$PYPROJECT_NAME" > /tmp/PYPROJECT_NAME && \
 | 
				
			||||||
 | 
					    echo "$DESCRIPTION" > /tmp/DESCRIPTION && \
 | 
				
			||||||
 | 
					    echo "$AUTHOR" > /tmp/AUTHOR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN --mount=type=bind,source=./.git/,target=/tmp/.git/ \
 | 
				
			||||||
 | 
					    echo "🏷️  Checking version information..." && \
 | 
				
			||||||
 | 
					    VERSION=$(git describe --tags --exact-match 2>/dev/null || git rev-parse --short HEAD || echo "unknown") && \
 | 
				
			||||||
 | 
					    echo "📌 Version: $VERSION" && \
 | 
				
			||||||
 | 
					    echo "$VERSION" > /tmp/VERSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LABEL org.opencontainers.image.created="$(cat /tmp/CREATED_DATE)" \
 | 
				
			||||||
 | 
					      org.opencontainers.image.authors="$(cat /tmp/AUTHOR)" \
 | 
				
			||||||
 | 
					      org.opencontainers.image.description="$(cat /tmp/DESCRIPTION)" \
 | 
				
			||||||
 | 
					      org.opencontainers.image.name="$(cat /tmp/PYPROJECT_NAME)" \
 | 
				
			||||||
 | 
					      org.opencontainers.image.version="$(cat /tmp/VERSION)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM node:20-slim AS frontend-stage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WORKDIR /tmp/admin-frontend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENV TZ=Asia/Shanghai \
 | 
				
			||||||
 | 
					    PNPM_HOME="/pnpm" \
 | 
				
			||||||
 | 
					    PATH="$PNPM_HOME:$PATH"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COPY ./admin-frontend/package.json ./admin-frontend/pnpm-lock.yaml ./
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN corepack enable && \
 | 
				
			||||||
 | 
					    corepack prepare pnpm@latest --activate && \
 | 
				
			||||||
 | 
					    echo "🔔 Verifying Node.js installation..." && \
 | 
				
			||||||
 | 
					    if NODE_VERSION=$(node --version 2>&1); then \
 | 
				
			||||||
 | 
					        echo "✅ Node.js version ${NODE_VERSION} installed successfully"; \
 | 
				
			||||||
 | 
					    else \
 | 
				
			||||||
 | 
					        echo "❌ Node.js installation failed" && exit 1; \
 | 
				
			||||||
 | 
					    fi && \
 | 
				
			||||||
 | 
					    echo "🔔 Verifying pnpm installation..." && \
 | 
				
			||||||
 | 
					    if PNPM_VERSION=$(pnpm --version 2>&1); then \
 | 
				
			||||||
 | 
					        echo "✅ pnpm version ${PNPM_VERSION} installed successfully"; \
 | 
				
			||||||
 | 
					    else \
 | 
				
			||||||
 | 
					        echo "❌ pnpm installation failed" && exit 1; \
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN pnpm install --frozen-lockfile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COPY ./admin-frontend .
 | 
				
			||||||
 | 
					RUN mkdir -p ../nonebot_bison/admin_page/dist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN echo "🏗️ Starting frontend build..." && \
 | 
				
			||||||
 | 
					    pnpm run build && \
 | 
				
			||||||
 | 
					    echo "✅ Frontend build completed"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS uv-stage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WORKDIR /app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENV DEBIAN_FRONTEND=noninteractive \
 | 
				
			||||||
 | 
					    PYTHONUNBUFFERED=1 \
 | 
				
			||||||
 | 
					    UV_COMPILE_BYTECODE=1 \
 | 
				
			||||||
 | 
					    UV_FROZEN=1 \
 | 
				
			||||||
 | 
					    UV_LINK_MODE=copy \
 | 
				
			||||||
 | 
					    TZ=Asia/Shanghai
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN echo "🔔 Verifying uv installation..." && \
 | 
				
			||||||
 | 
					    if UV_VERSION=$(uv --version 2>&1); then \
 | 
				
			||||||
 | 
					        echo "✅ uv version ${UV_VERSION} installed successfully"; \
 | 
				
			||||||
 | 
					    else \
 | 
				
			||||||
 | 
					        echo "❌ uv installation failed" && exit 1; \
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN --mount=type=cache,target=/root/.cache/uv \
 | 
				
			||||||
 | 
					    --mount=type=bind,source=uv.lock,target=uv.lock \
 | 
				
			||||||
 | 
					    --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
 | 
				
			||||||
 | 
					    echo "📦 Installing project dependencies..." && \
 | 
				
			||||||
 | 
					    uv sync --no-install-project --no-dev --extra docker && \
 | 
				
			||||||
 | 
					    echo "✅ Dependencies installed successfully"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS production
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WORKDIR /app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENV DEBIAN_FRONTEND=noninteractive \
 | 
				
			||||||
 | 
					    PYTHONUNBUFFERED=1 \
 | 
				
			||||||
 | 
					    UV_COMPILE_BYTECODE=1 \
 | 
				
			||||||
 | 
					    UV_FROZEN=1 \
 | 
				
			||||||
 | 
					    UV_LINK_MODE=copy \
 | 
				
			||||||
 | 
					    TZ=Asia/Shanghai \
 | 
				
			||||||
 | 
					    SHELL="/bin/bash"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 少变动的放上面,频繁变动的放下面
 | 
				
			||||||
 | 
					COPY ./docker.env.prod ./.env
 | 
				
			||||||
 | 
					COPY extra_plugins/ /app/extra_plugins/
 | 
				
			||||||
 | 
					COPY --from=frontend-stage /tmp/nonebot_bison/admin_page/dist ./nonebot_bison/admin_page/dist
 | 
				
			||||||
 | 
					COPY --from=uv-stage /app /app
 | 
				
			||||||
 | 
					COPY ./pyproject.toml ./uv.lock ./README.md ./
 | 
				
			||||||
 | 
					COPY nonebot_bison/ /app/nonebot_bison/
 | 
				
			||||||
 | 
					COPY --from=metadata-stage /tmp/VERSION /app/VERSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN --mount=type=cache,target=/root/.cache/uv \
 | 
				
			||||||
 | 
					    echo "📦 Installing bison project..." && \
 | 
				
			||||||
 | 
					    uv sync --no-dev --extra docker && \
 | 
				
			||||||
 | 
					    uv run nb adapter install nonebot-adapter-satori && \
 | 
				
			||||||
 | 
					    uv run nb adapter install nonebot-adapter-qq && \
 | 
				
			||||||
 | 
					    uv run nb plugin install nonebot-plugin-sentry && \
 | 
				
			||||||
 | 
					    echo "✅ Bison installed successfully"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPOSE 8080
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENV BISON_SKIP_BROWSER_CHECK=True \
 | 
				
			||||||
 | 
					    BISON_USE_BROWSER=False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN echo '#!/bin/bash' > /app/start.sh && \
 | 
				
			||||||
 | 
					    echo 'echo "📌 Current bison Version: $(cat /app/VERSION)"' >> /app/start.sh && \
 | 
				
			||||||
 | 
					    echo 'echo "🚀 Starting service..."' >> /app/start.sh && \
 | 
				
			||||||
 | 
					    echo 'source /app/.venv/bin/activate' >> /app/start.sh && \
 | 
				
			||||||
 | 
					    echo 'nb run' >> /app/start.sh && \
 | 
				
			||||||
 | 
					    chmod +x /app/start.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CMD ["/app/start.sh"]
 | 
				
			||||||
@ -8,7 +8,7 @@ next: /dev/cookie
 | 
				
			|||||||
## 语言以及工具
 | 
					## 语言以及工具
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. 本项目使用了`python3.10`的特性进行开发,所以请确保你的 Python 版本>=3.10
 | 
					1. 本项目使用了`python3.10`的特性进行开发,所以请确保你的 Python 版本>=3.10
 | 
				
			||||||
2. 本项目使用 poetry 进行依赖管理,请确保开发之前已经进行过`poetry install`,运行时在`poetry shell`的环境中进行运行
 | 
					2. 本项目使用 uv 进行依赖管理,请确保开发之前已经进行过`uv sync`,运行时在`uv venv`的环境中进行运行
 | 
				
			||||||
3. 本项目使用的 node 项目管理工具是 pnpm
 | 
					3. 本项目使用的 node 项目管理工具是 pnpm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
::: tip 参考
 | 
					::: tip 参考
 | 
				
			||||||
@ -30,7 +30,7 @@ next: /dev/cookie
 | 
				
			|||||||
2. 运行 bot
 | 
					2. 运行 bot
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   ```bash
 | 
					   ```bash
 | 
				
			||||||
   poetry run nb run
 | 
					   uv run nb run
 | 
				
			||||||
   ```
 | 
					   ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
3. 运行前端:
 | 
					3. 运行前端:
 | 
				
			||||||
@ -50,7 +50,7 @@ next: /dev/cookie
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## 代码格式
 | 
					## 代码格式
 | 
				
			||||||
 | 
					
 | 
				
			||||||
本项目使用了 pre-commit 来进行代码美化和格式化。在`poetry shell`状态下执行`pre-commit install`来安装 git hook,可自动在 commit 时
 | 
					本项目使用了 pre-commit 来进行代码美化和格式化。在`uv venv`状态下执行`pre-commit install`来安装 git hook,可自动在 commit 时
 | 
				
			||||||
格式化代码。
 | 
					格式化代码。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 适配新网站
 | 
					## 适配新网站
 | 
				
			||||||
 | 
				
			|||||||
@ -83,10 +83,8 @@ sequenceDiagram
 | 
				
			|||||||
目前 CookieClientManager 具有以下方法
 | 
					目前 CookieClientManager 具有以下方法
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- `refresh_anonymous_cookie(cls)` 移除已有的匿名 cookie,添加一个新的匿名 cookie,应该在 CCM 初始化时调用
 | 
					- `refresh_anonymous_cookie(cls)` 移除已有的匿名 cookie,添加一个新的匿名 cookie,应该在 CCM 初始化时调用
 | 
				
			||||||
- `add_user_cookie(cls, content: str)` 添加用户 cookie,在这里对 Cookie 进行检查并获取 cookie_name,写入数据库
 | 
					 | 
				
			||||||
- `_generate_hook(self, cookie: Cookie) -> Callable` hook 函数生成器,用于回写请求状态到数据库
 | 
					 | 
				
			||||||
- `_choose_cookie(self, target: Target) -> Cookie` 选择 cookie 的具体算法
 | 
					- `_choose_cookie(self, target: Target) -> Cookie` 选择 cookie 的具体算法
 | 
				
			||||||
- `add_user_cookie(cls, content: str, cookie_name: str | None = None) -> Cookie` 对外的接口,添加用户 cookie,内部会调用 Site 的方法进行检查
 | 
					- `add_identified_cookie(cls, content: str, cookie_name: str | None = None) -> Cookie` 对外的接口,添加实名 cookie,内部会调用 Site 的方法进行检查
 | 
				
			||||||
- `get_client(self, target: Target | None) -> AsyncClient` 对外的接口,获取 client,根据 target 选择 cookie
 | 
					- `get_client(self, target: Target | None) -> AsyncClient` 对外的接口,获取 client,根据 target 选择 cookie
 | 
				
			||||||
- `_assemble_client(self, client, cookie) -> AsyncClient` 组装 client,可以自定义 cookie 对象的 content 装配到 client 中的方式
 | 
					- `_assemble_client(self, client, cookie) -> AsyncClient` 组装 client,可以自定义 cookie 对象的 content 装配到 client 中的方式
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -100,7 +98,7 @@ sequenceDiagram
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
简单来说:
 | 
					简单来说:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- 如果需要修改 Cookie 的默认参数,可以重写`add_user_cookie`方法,这里设置需要的字段
 | 
					- 如果需要修改 Cookie 的默认参数,可以重写`add_identified_cookie`方法,这里设置需要的字段
 | 
				
			||||||
- 如果需要修改选择 Cookie 的逻辑,可以重写`_choose_cookie`方法,使用自己的算法选择合适的 Cookie 并返回
 | 
					- 如果需要修改选择 Cookie 的逻辑,可以重写`_choose_cookie`方法,使用自己的算法选择合适的 Cookie 并返回
 | 
				
			||||||
- 如果需要自定义 Cookie 的格式,可以重写`valid_cookie`方法,自定义验证 Cookie 的逻辑,并重写`_assemble_client`方法,自定义将 Cookie 装配到 Client 中的逻辑
 | 
					- 如果需要自定义 Cookie 的格式,可以重写`valid_cookie`方法,自定义验证 Cookie 的逻辑,并重写`_assemble_client`方法,自定义将 Cookie 装配到 Client 中的逻辑
 | 
				
			||||||
- 如果要在请求结束后做一些操作(例如保存此次请求的结果/状态),可以重写`_response_hook`方法,自定义请求结束后的行为
 | 
					- 如果要在请求结束后做一些操作(例如保存此次请求的结果/状态),可以重写`_response_hook`方法,自定义请求结束后的行为
 | 
				
			||||||
@ -137,7 +135,7 @@ sequenceDiagram
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
- **无 Target 平台的 Cookie 处理方式**
 | 
					- **无 Target 平台的 Cookie 处理方式**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  对于不存在 Target 的平台,如小刻食堂,可以重写 add_user_cookie 方法,为用户 Cookie 设置 is_universal 字段。这样,在获取 Client 时,由于传入的 Target 为空,就只会选择 is_universal 的 cookie。实现了无 Target 平台的用户 Cookie 调度。
 | 
					  对于不存在 Target 的平台,如小刻食堂,可以重写 add_identified_cookie 方法,为实名 cookie 设置 is_universal 字段。这样,在获取 Client 时,由于传入的 Target 为空,就只会选择 is_universal 的 cookie。实现了无 Target 平台的实名 cookie 调度。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 默认的调度策略
 | 
					## 默认的调度策略
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -23,7 +23,7 @@ next: /usage/easy-use
 | 
				
			|||||||
参考视频教程 [保姆级新手教学 - Well404](https://www.bilibili.com/video/BV1984y1b7JY)
 | 
					参考视频教程 [保姆级新手教学 - Well404](https://www.bilibili.com/video/BV1984y1b7JY)
 | 
				
			||||||
:::
 | 
					:::
 | 
				
			||||||
::: warning 防止环境冲突!
 | 
					::: warning 防止环境冲突!
 | 
				
			||||||
建议所有操作都在虚拟环境下进行,推荐使用[`poetry`](https://python-poetry.org/)或者 python 自带的[`venv`](https://docs.python.org/zh-cn/3/library/venv.html)
 | 
					建议所有操作都在虚拟环境下进行,推荐使用[`uv`](https://docs.astral.sh/uv/)或者 python 自带的[`venv`](https://docs.python.org/zh-cn/3/library/venv.html)
 | 
				
			||||||
:::
 | 
					:::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### 使用 nb-cli 安装 <Badge type="tip" text="推荐" vertical="top" />
 | 
					### 使用 nb-cli 安装 <Badge type="tip" text="推荐" vertical="top" />
 | 
				
			||||||
@ -43,17 +43,17 @@ next: /usage/easy-use
 | 
				
			|||||||
3. 在项目中添加依赖
 | 
					3. 在项目中添加依赖
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   ```bash
 | 
					   ```bash
 | 
				
			||||||
   poetry add nonebot-bison
 | 
					   uv add nonebot-bison
 | 
				
			||||||
   ```
 | 
					   ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### 手动安装
 | 
					### 手动安装
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. 安装 pip 包`nonebot-bison`
 | 
					1. 安装 pip 包`nonebot-bison`
 | 
				
			||||||
   ::: code-tabs
 | 
					   ::: code-tabs
 | 
				
			||||||
   @tab poetry
 | 
					   @tab uv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   ```bash
 | 
					   ```bash
 | 
				
			||||||
   poetry add nonebot-bison
 | 
					   uv add nonebot-bison
 | 
				
			||||||
   ```
 | 
					   ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   @tab pip
 | 
					   @tab pip
 | 
				
			||||||
@ -169,13 +169,13 @@ Bison 的 WebUI 是需要编译后才能使用的,直接克隆源代码需要
 | 
				
			|||||||
本项目中使用了 Python 3.10 的语法,如果出现问题,请检查 Python 版本
 | 
					本项目中使用了 Python 3.10 的语法,如果出现问题,请检查 Python 版本
 | 
				
			||||||
:::
 | 
					:::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. 首先安装 poetry:[安装方法](https://python-poetry.org/docs/#installation)
 | 
					1. 首先安装 uv:[安装方法](https://docs.astral.sh/uv/getting-started/installation/)
 | 
				
			||||||
2. clone 本项目,在项目中`poetry install`安装依赖
 | 
					2. clone 本项目,在项目中使用`uv sync`安装依赖
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   ```bash
 | 
					   ```bash
 | 
				
			||||||
   git clone https://github.com/felinae98/nonebot-bison.git
 | 
					   git clone https://github.com/felinae98/nonebot-bison.git
 | 
				
			||||||
   cd nonebot-bison
 | 
					   cd nonebot-bison
 | 
				
			||||||
   poetry install
 | 
					   uv sync
 | 
				
			||||||
   ```
 | 
					   ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#### WebUI 安装
 | 
					#### WebUI 安装
 | 
				
			||||||
@ -235,5 +235,5 @@ Bison 的 WebUI 是需要编译后才能使用的,直接克隆源代码需要
 | 
				
			|||||||
2. 启动 Bot
 | 
					2. 启动 Bot
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   ```bash
 | 
					   ```bash
 | 
				
			||||||
   poetry run nb run
 | 
					   uv run nb run
 | 
				
			||||||
   ```
 | 
					   ```
 | 
				
			||||||
 | 
				
			|||||||
@ -235,7 +235,7 @@ async def get_cookie(site_name: str | None = None, target: str | None = None) ->
 | 
				
			|||||||
@router.post("/cookie", dependencies=[Depends(check_is_superuser)])
 | 
					@router.post("/cookie", dependencies=[Depends(check_is_superuser)])
 | 
				
			||||||
async def add_cookie(site_name: str, content: str) -> StatusResp:
 | 
					async def add_cookie(site_name: str, content: str) -> StatusResp:
 | 
				
			||||||
    client_mgr = cast(CookieClientManager, scheduler_dict[site_manager[site_name]].client_mgr)
 | 
					    client_mgr = cast(CookieClientManager, scheduler_dict[site_manager[site_name]].client_mgr)
 | 
				
			||||||
    await client_mgr.add_user_cookie(content)
 | 
					    await client_mgr.add_identified_cookie(content)
 | 
				
			||||||
    return StatusResp(ok=True, msg="")
 | 
					    return StatusResp(ok=True, msg="")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -12,14 +12,16 @@ from playwright.async_api import Cookie
 | 
				
			|||||||
from nonebot_bison.config import config
 | 
					from nonebot_bison.config import config
 | 
				
			||||||
from nonebot_bison.config.db_model import Cookie as CookieModel
 | 
					from nonebot_bison.config.db_model import Cookie as CookieModel
 | 
				
			||||||
from nonebot_bison.config.db_model import Target
 | 
					from nonebot_bison.config.db_model import Target
 | 
				
			||||||
 | 
					from nonebot_bison.plugin_config import plugin_config
 | 
				
			||||||
from nonebot_bison.utils import Site, http_client
 | 
					from nonebot_bison.utils import Site, http_client
 | 
				
			||||||
from nonebot_bison.utils.site import CookieClientManager
 | 
					from nonebot_bison.utils.site import CookieClientManager
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if TYPE_CHECKING:
 | 
					if TYPE_CHECKING:
 | 
				
			||||||
    from .platforms import Bilibili
 | 
					    from .platforms import Bilibili
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require("nonebot_plugin_htmlrender")
 | 
					if plugin_config.bison_use_browser:
 | 
				
			||||||
from nonebot_plugin_htmlrender import get_browser
 | 
					    require("nonebot_plugin_htmlrender")
 | 
				
			||||||
 | 
					    from nonebot_plugin_htmlrender import get_browser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
B = TypeVar("B", bound="Bilibili")
 | 
					B = TypeVar("B", bound="Bilibili")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -76,7 +76,7 @@ def do_add_cookie(add_cookie: type[Matcher]):
 | 
				
			|||||||
    @add_cookie.handle()
 | 
					    @add_cookie.handle()
 | 
				
			||||||
    async def add_cookie_process(state: T_State):
 | 
					    async def add_cookie_process(state: T_State):
 | 
				
			||||||
        client_mgr = cast(CookieClientManager, scheduler_dict[platform_manager[state["platform"]].site].client_mgr)
 | 
					        client_mgr = cast(CookieClientManager, scheduler_dict[platform_manager[state["platform"]].site].client_mgr)
 | 
				
			||||||
        new_cookie = await client_mgr.add_user_cookie(state["cookie"], state["cookie_name"])
 | 
					        new_cookie = await client_mgr.add_identified_cookie(state["cookie"], state["cookie_name"])
 | 
				
			||||||
        await add_cookie.finish(
 | 
					        await add_cookie.finish(
 | 
				
			||||||
            f"已添加 Cookie: {new_cookie.cookie_name} 到平台 {state['platform']}"
 | 
					            f"已添加 Cookie: {new_cookie.cookie_name} 到平台 {state['platform']}"
 | 
				
			||||||
            + "\n请使用“关联cookie”为 Cookie 关联订阅"
 | 
					            + "\n请使用“关联cookie”为 Cookie 关联订阅"
 | 
				
			||||||
 | 
				
			|||||||
@ -34,7 +34,7 @@ def do_add_cookie_target(add_cookie_target_matcher: type[Matcher]):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @add_cookie_target_matcher.handle()
 | 
					    @add_cookie_target_matcher.handle()
 | 
				
			||||||
    async def init_promote_cookie(state: T_State):
 | 
					    async def init_promote_cookie(state: T_State):
 | 
				
			||||||
        # 获取 site 的所有用户 cookie,再排除掉已经关联的 cookie,剩下的就是可以关联的 cookie
 | 
					        # 获取 site 的所有实名 cookie,再排除掉已经关联的 cookie,剩下的就是可以关联的 cookie
 | 
				
			||||||
        cookies = await config.get_cookie(site_name=state["site"].name, is_anonymous=False)
 | 
					        cookies = await config.get_cookie(site_name=state["site"].name, is_anonymous=False)
 | 
				
			||||||
        associated_cookies = await config.get_cookie(
 | 
					        associated_cookies = await config.get_cookie(
 | 
				
			||||||
            target=state["target"]["target"],
 | 
					            target=state["target"]["target"],
 | 
				
			||||||
 | 
				
			|||||||
@ -79,8 +79,8 @@ class CookieClientManager(ClientManager):
 | 
				
			|||||||
            new_anonymous_cookie = await self._generate_anonymous_cookie()
 | 
					            new_anonymous_cookie = await self._generate_anonymous_cookie()
 | 
				
			||||||
            await config.add_cookie(new_anonymous_cookie)
 | 
					            await config.add_cookie(new_anonymous_cookie)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def add_user_cookie(self, content: str, cookie_name: str | None = None) -> Cookie:
 | 
					    async def add_identified_cookie(self, content: str, cookie_name: str | None = None) -> Cookie:
 | 
				
			||||||
        """添加用户 cookie"""
 | 
					        """添加实名 cookie"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not await self.validate_cookie(content):
 | 
					        if not await self.validate_cookie(content):
 | 
				
			||||||
            raise ValueError()
 | 
					            raise ValueError()
 | 
				
			||||||
@ -133,9 +133,9 @@ class CookieClientManager(ClientManager):
 | 
				
			|||||||
        client = http_client()
 | 
					        client = http_client()
 | 
				
			||||||
        cookie = await self._choose_cookie(target)
 | 
					        cookie = await self._choose_cookie(target)
 | 
				
			||||||
        if cookie.is_universal:
 | 
					        if cookie.is_universal:
 | 
				
			||||||
            logger.trace(f"平台 {self._site_name} 未获取到用户cookie, 使用匿名cookie")
 | 
					            logger.trace(f"平台 {self._site_name} 未获取到实名cookie, 使用匿名cookie")
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            logger.trace(f"平台 {self._site_name} 获取到用户cookie: {cookie.id}")
 | 
					            logger.trace(f"平台 {self._site_name} 获取到实名cookie: {cookie.id}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return await self._assemble_client(client, cookie)
 | 
					        return await self._assemble_client(client, cookie)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -185,7 +185,7 @@ class SiteMeta(type):
 | 
				
			|||||||
        elif not kwargs.get("abstract"):
 | 
					        elif not kwargs.get("abstract"):
 | 
				
			||||||
            # this is the subclass
 | 
					            # this is the subclass
 | 
				
			||||||
            if "name" in namespace:
 | 
					            if "name" in namespace:
 | 
				
			||||||
                site_manager[namespace["name"]] = cls
 | 
					                site_manager[namespace["name"]] = cls  # type: ignore[reportArgumentType]
 | 
				
			||||||
        super().__init__(name, bases, namespace, **kwargs)
 | 
					        super().__init__(name, bases, namespace, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										5067
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5067
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										134
									
								
								pyproject.toml
									
									
									
									
									
								
							
							
						
						
									
										134
									
								
								pyproject.toml
									
									
									
									
									
								
							@ -1,13 +1,34 @@
 | 
				
			|||||||
[tool.poetry]
 | 
					[project]
 | 
				
			||||||
 | 
					authors = [{ name = "felinae98", email = "felinae225@qq.com" }]
 | 
				
			||||||
 | 
					license = { text = "MIT" }
 | 
				
			||||||
 | 
					requires-python = "<4.0.0,>=3.10"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					  "beautifulsoup4>=4.12.3",
 | 
				
			||||||
 | 
					  "feedparser<7.0.0,>=6.0.11",
 | 
				
			||||||
 | 
					  "httpx>=0.27.2",
 | 
				
			||||||
 | 
					  "nonebot2[fastapi]<3.0.0,>=2.3.3",
 | 
				
			||||||
 | 
					  "nonebot-adapter-onebot<3.0.0,>=2.4.5",
 | 
				
			||||||
 | 
					  "nonebot-plugin-htmlrender>=0.3.5,!=0.5.0",
 | 
				
			||||||
 | 
					  "nonebot-plugin-datastore<2.0.0,>=1.3.0",
 | 
				
			||||||
 | 
					  "nonebot-plugin-apscheduler>=0.5.0",
 | 
				
			||||||
 | 
					  "nonebot-plugin-send-anything-anywhere<0.7.2,>=0.7.1",
 | 
				
			||||||
 | 
					  "pillow<11.1,>=11.0.0",
 | 
				
			||||||
 | 
					  "pyjwt<3.0.0,>=2.9.0",
 | 
				
			||||||
 | 
					  "python-socketio<6.0.0,>=5.11.4",
 | 
				
			||||||
 | 
					  "tinydb<5.0.0,>=4.8.0",
 | 
				
			||||||
 | 
					  "qrcode<8.0.0,>=7.4.2",
 | 
				
			||||||
 | 
					  "pydantic!=2.5.0,!=2.5.1,<3.0.0,>=2.9.2",
 | 
				
			||||||
 | 
					  "lxml>=5.3.0",
 | 
				
			||||||
 | 
					  "yarl>=1.11.1",
 | 
				
			||||||
 | 
					  "hishel<1.0.0,>=0.0.30",
 | 
				
			||||||
 | 
					  "expiringdictx<2.0.0,>=1.1.0",
 | 
				
			||||||
 | 
					  "rapidfuzz<4.0.0,>=3.9.7",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
name = "nonebot-bison"
 | 
					name = "nonebot-bison"
 | 
				
			||||||
version = "0.9.5"
 | 
					version = "0.9.5"
 | 
				
			||||||
description = "Subscribe message from social medias"
 | 
					description = "Subscribe message from social medias"
 | 
				
			||||||
authors = ["felinae98 <felinae225@qq.com>"]
 | 
					 | 
				
			||||||
license = "MIT"
 | 
					 | 
				
			||||||
homepage = "https://github.com/felinae98/nonebot-bison"
 | 
					 | 
				
			||||||
keywords = ["nonebot", "nonebot2", "qqbot"]
 | 
					keywords = ["nonebot", "nonebot2", "qqbot"]
 | 
				
			||||||
readme = "README.md"
 | 
					readme = "README.md"
 | 
				
			||||||
include = ["nonebot_bison/admin_page/dist/**/*"]
 | 
					 | 
				
			||||||
classifiers = [
 | 
					classifiers = [
 | 
				
			||||||
  "Development Status :: 4 - Beta",
 | 
					  "Development Status :: 4 - Beta",
 | 
				
			||||||
  "Operating System :: POSIX :: Linux",
 | 
					  "Operating System :: POSIX :: Linux",
 | 
				
			||||||
@ -20,69 +41,49 @@ classifiers = [
 | 
				
			|||||||
  "License :: OSI Approved :: MIT License",
 | 
					  "License :: OSI Approved :: MIT License",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[tool.poetry.dependencies]
 | 
					[project.urls]
 | 
				
			||||||
python = ">=3.10,<4.0.0"
 | 
					homepage = "https://github.com/felinae98/nonebot-bison"
 | 
				
			||||||
beautifulsoup4 = ">=4.12.3"
 | 
					 | 
				
			||||||
feedparser = "^6.0.11"
 | 
					 | 
				
			||||||
httpx = ">=0.27.2"
 | 
					 | 
				
			||||||
nonebot2 = { extras = ["fastapi"], version = "^2.3.3" }
 | 
					 | 
				
			||||||
nonebot-adapter-onebot = "^2.4.5"
 | 
					 | 
				
			||||||
nonebot-plugin-htmlrender = ">=0.3.5"
 | 
					 | 
				
			||||||
nonebot-plugin-datastore = ">=1.3.0,<2.0.0"
 | 
					 | 
				
			||||||
nonebot-plugin-apscheduler = ">=0.5.0"
 | 
					 | 
				
			||||||
nonebot-plugin-send-anything-anywhere = ">=0.7.1,<0.7.2"
 | 
					 | 
				
			||||||
pillow = ">=11.0.0,<11.1"
 | 
					 | 
				
			||||||
pyjwt = "^2.9.0"
 | 
					 | 
				
			||||||
python-socketio = "^5.11.4"
 | 
					 | 
				
			||||||
tinydb = "^4.8.0"
 | 
					 | 
				
			||||||
qrcode = "^7.4.2"
 | 
					 | 
				
			||||||
pydantic = ">=2.9.2,<3.0.0,!=2.5.0,!=2.5.1"
 | 
					 | 
				
			||||||
lxml = ">=5.3.0"
 | 
					 | 
				
			||||||
yarl = ">=1.11.1"
 | 
					 | 
				
			||||||
hishel = "^0.0.30"
 | 
					 | 
				
			||||||
expiringdictx = "^1.1.0"
 | 
					 | 
				
			||||||
rapidfuzz = "^3.9.7"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
[tool.poetry.group.dev.dependencies]
 | 
					[project.entry-points.nb_scripts]
 | 
				
			||||||
ipdb = "^0.13.13"
 | 
					 | 
				
			||||||
nonemoji = "^0.1.4"
 | 
					 | 
				
			||||||
nb-cli = "^1.4.2"
 | 
					 | 
				
			||||||
pre-commit = "^4.0.1"
 | 
					 | 
				
			||||||
ruff = "^0.8.2"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[tool.poetry.group.test.dependencies]
 | 
					 | 
				
			||||||
flaky = "^3.8.1"
 | 
					 | 
				
			||||||
nonebug = "^0.3.7"
 | 
					 | 
				
			||||||
nonebug-saa = "^0.4.1"
 | 
					 | 
				
			||||||
pytest = ">=8.3.3,<9.0.0"
 | 
					 | 
				
			||||||
pytest-asyncio = ">=0.24.0,<0.24.1"
 | 
					 | 
				
			||||||
pytest-cov = ">=6.0.0,<7"
 | 
					 | 
				
			||||||
pytest-mock = "^3.14.0"
 | 
					 | 
				
			||||||
pytest-xdist = { extras = ["psutil"], version = "^3.6.1" }
 | 
					 | 
				
			||||||
respx = ">=0.21.1,<0.22"
 | 
					 | 
				
			||||||
freezegun = "^1.5.1"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[tool.poetry.group.docker]
 | 
					 | 
				
			||||||
optional = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[tool.poetry.group.docker.dependencies]
 | 
					 | 
				
			||||||
nb-cli = "^1.4.2"
 | 
					 | 
				
			||||||
nonebot2 = { extras = ["fastapi", "aiohttp"], version = "^2.3.3" }
 | 
					 | 
				
			||||||
nonebot-adapter-red = "^0.9.0"
 | 
					 | 
				
			||||||
nonebot-adapter-qq = "^1.5.1"
 | 
					 | 
				
			||||||
poetry-core = "^1.9.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[tool.poetry.extras]
 | 
					 | 
				
			||||||
cli = ["anyio", "click", "typing-extensions"]
 | 
					 | 
				
			||||||
yaml = ["pyyaml"]
 | 
					 | 
				
			||||||
all = ["anyio", "click", "typing-extensions", "pyyaml"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[tool.poetry.plugins.nb_scripts]
 | 
					 | 
				
			||||||
bison = "nonebot_bison.script.cli:main"
 | 
					bison = "nonebot_bison.script.cli:main"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependency-groups]
 | 
				
			||||||
 | 
					dev = [
 | 
				
			||||||
 | 
					  "ipdb<1.0.0,>=0.13.13",
 | 
				
			||||||
 | 
					  "nonemoji<1.0.0,>=0.1.4",
 | 
				
			||||||
 | 
					  "nb-cli<2.0.0,>=1.4.2",
 | 
				
			||||||
 | 
					  "pre-commit<5.0.0,>=4.0.1",
 | 
				
			||||||
 | 
					  "ruff<1.0.0,>=0.8.2",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					test = [
 | 
				
			||||||
 | 
					  "flaky<4.0.0,>=3.8.1",
 | 
				
			||||||
 | 
					  "nonebug<1.0.0,>=0.3.7",
 | 
				
			||||||
 | 
					  "nonebug-saa<1.0.0,>=0.4.1",
 | 
				
			||||||
 | 
					  "pytest<9.0.0,>=8.3.3",
 | 
				
			||||||
 | 
					  "pytest-asyncio<0.24.1,>=0.24.0",
 | 
				
			||||||
 | 
					  "pytest-cov<7,>=6.0.0",
 | 
				
			||||||
 | 
					  "pytest-mock<4.0.0,>=3.14.0",
 | 
				
			||||||
 | 
					  "pytest-xdist[psutil]<4.0.0,>=3.6.1",
 | 
				
			||||||
 | 
					  "respx<0.23.0,>=0.22.0",
 | 
				
			||||||
 | 
					  "freezegun<2.0.0,>=1.5.1",
 | 
				
			||||||
 | 
					  "pytz>=2024.2",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[project.optional-dependencies]
 | 
				
			||||||
 | 
					docker = [
 | 
				
			||||||
 | 
					  "nb-cli<2.0.0,>=1.4.2",
 | 
				
			||||||
 | 
					  "nonebot2[aiohttp,fastapi]<3.0.0,>=2.3.3",
 | 
				
			||||||
 | 
					  "nonebot-adapter-qq<2.0.0,>=1.5.1",
 | 
				
			||||||
 | 
					  "nonebot-adapter-satori>=0.13.1",
 | 
				
			||||||
 | 
					  "pip>=24.3.1",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[tool.uv]
 | 
				
			||||||
 | 
					default-groups = ["dev", "test"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[build-system]
 | 
					[build-system]
 | 
				
			||||||
requires = ["poetry-core>=1.9.0"]
 | 
					requires = ["pdm-backend"]
 | 
				
			||||||
build-backend = "poetry.core.masonry.api"
 | 
					build-backend = "pdm.backend"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[tool.pytest.ini_options]
 | 
					[tool.pytest.ini_options]
 | 
				
			||||||
markers = [
 | 
					markers = [
 | 
				
			||||||
@ -157,8 +158,3 @@ executionEnvironments = [
 | 
				
			|||||||
  { root = "./" },
 | 
					  { root = "./" },
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
defineConstant = { PYDANTIC_V2 = true }
 | 
					defineConstant = { PYDANTIC_V2 = true }
 | 
				
			||||||
 | 
					 | 
				
			||||||
[[tool.poetry.source]]
 | 
					 | 
				
			||||||
name = "offical-source"
 | 
					 | 
				
			||||||
url = "https://pypi.org/simple/"
 | 
					 | 
				
			||||||
priority = "primary"
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -34,9 +34,9 @@ async def test_cookie(app: App, init_scheduler):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    cookies = await config.get_cookie(site_name=site.name)
 | 
					    cookies = await config.get_cookie(site_name=site.name)
 | 
				
			||||||
    assert len(cookies) == 1
 | 
					    assert len(cookies) == 1
 | 
				
			||||||
    # 添加用户cookie
 | 
					    # 添加实名cookie
 | 
				
			||||||
    await client_mgr.add_user_cookie(json.dumps({"test_cookie": "1"}))
 | 
					    await client_mgr.add_identified_cookie(json.dumps({"test_cookie": "1"}))
 | 
				
			||||||
    await client_mgr.add_user_cookie(json.dumps({"test_cookie": "2"}))
 | 
					    await client_mgr.add_identified_cookie(json.dumps({"test_cookie": "2"}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cookies = await config.get_cookie(site_name=site.name)
 | 
					    cookies = await config.get_cookie(site_name=site.name)
 | 
				
			||||||
    assert len(cookies) == 3
 | 
					    assert len(cookies) == 3
 | 
				
			||||||
@ -68,7 +68,7 @@ async def test_cookie(app: App, init_scheduler):
 | 
				
			|||||||
        tags=[],
 | 
					        tags=[],
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await client_mgr.add_user_cookie(json.dumps({"test_cookie": "3"}))
 | 
					    await client_mgr.add_identified_cookie(json.dumps({"test_cookie": "3"}))
 | 
				
			||||||
    cookies = await config.get_cookie(site_name=site.name, is_anonymous=False)
 | 
					    cookies = await config.get_cookie(site_name=site.name, is_anonymous=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # 多个target,多个cookie
 | 
					    # 多个target,多个cookie
 | 
				
			||||||
 | 
				
			|||||||
@ -4,31 +4,7 @@ from nonebug.app import App
 | 
				
			|||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
from pytest_mock import MockerFixture
 | 
					from pytest_mock import MockerFixture
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from tests.utils import BotReply, fake_admin_user, fake_private_message_event, fake_superuser
 | 
					from tests.utils import BotReply, fake_private_message_event, fake_superuser
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async def test_add_cookie_rule(app: App, mocker: MockerFixture):
 | 
					 | 
				
			||||||
    from nonebot.adapters.onebot.v11.bot import Bot
 | 
					 | 
				
			||||||
    from nonebot.adapters.onebot.v11.message import Message
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    from nonebot_bison.plugin_config import plugin_config
 | 
					 | 
				
			||||||
    from nonebot_bison.sub_manager import add_cookie_matcher
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    mocker.patch.object(plugin_config, "bison_to_me", True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async with app.test_matcher(add_cookie_matcher) as ctx:
 | 
					 | 
				
			||||||
        bot = ctx.create_bot(base=Bot)
 | 
					 | 
				
			||||||
        event = fake_private_message_event(message=Message("添加cookie"), sender=fake_superuser)
 | 
					 | 
				
			||||||
        ctx.receive_event(bot, event)
 | 
					 | 
				
			||||||
        ctx.should_pass_rule()
 | 
					 | 
				
			||||||
        ctx.should_pass_permission()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async with app.test_matcher(add_cookie_matcher) as ctx:
 | 
					 | 
				
			||||||
        bot = ctx.create_bot(base=Bot)
 | 
					 | 
				
			||||||
        event = fake_private_message_event(message=Message("添加cookie"), sender=fake_admin_user)
 | 
					 | 
				
			||||||
        ctx.receive_event(bot, event)
 | 
					 | 
				
			||||||
        ctx.should_not_pass_rule()
 | 
					 | 
				
			||||||
        ctx.should_pass_permission()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.mark.usefixtures("_clear_db")
 | 
					@pytest.mark.usefixtures("_clear_db")
 | 
				
			||||||
 | 
				
			|||||||
@ -42,4 +42,5 @@ async def test_without_permission(app: App):
 | 
				
			|||||||
            True,
 | 
					            True,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        ctx.should_pass_rule()
 | 
					        ctx.should_pass_rule()
 | 
				
			||||||
        ctx.should_pass_permission()
 | 
					        ctx.should_pass_permission(no_permission_matcher)
 | 
				
			||||||
 | 
					        ctx.should_not_pass_permission(add_sub_matcher)
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,6 @@ async def test_http_error(app: App):
 | 
				
			|||||||
        "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 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
 | 
					        " 'connection': 'keep-alive', 'user-agent': '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'}) | [403] Headers({'content-length': '"
 | 
					        " (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0'}) | [403] Headers({'content-length': '"
 | 
				
			||||||
        "15', 'content-type':"
 | 
					        "14', 'content-type':"
 | 
				
			||||||
        ' \'application/json\'}) {"error": "gg"}'
 | 
					        ' \'application/json\'}) {"error":"gg"}'
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user