mirror of
https://github.com/suyiiyii/nonebot-bison.git
synced 2026-05-11 03:18:29 +08:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
1031e9f9a5
|
|||
|
57e68ac0b9
|
|||
|
29a807df5a
|
|||
|
59846642cc
|
|||
| e45bf03e49 | |||
| 3421e3ac5e |
+8
-13
@@ -1,24 +1,19 @@
|
|||||||
*.ini
|
*.ini
|
||||||
#*.yaml
|
*.yaml
|
||||||
*.yml
|
*.yml
|
||||||
*.md
|
*.md
|
||||||
#*.json
|
*.json
|
||||||
|
*.toml
|
||||||
*.xml
|
*.xml
|
||||||
tests
|
tests
|
||||||
node_modules
|
node_modules
|
||||||
#admin-frontend
|
admin-frontend
|
||||||
data*
|
data*
|
||||||
htmlcov
|
htmlcov
|
||||||
docker
|
docker
|
||||||
dist
|
dist
|
||||||
docs
|
docs
|
||||||
venv
|
.*
|
||||||
.venv
|
|
||||||
/admin-frontend/node_modules
|
!pyproject.toml
|
||||||
/LICENSE
|
!README.md
|
||||||
/.editorconfig
|
|
||||||
/.gitattributes
|
|
||||||
/.prettierignore
|
|
||||||
/.prettierrc
|
|
||||||
/.devcontainer/
|
|
||||||
/.github/
|
|
||||||
|
|||||||
@@ -6,10 +6,6 @@ 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"
|
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
@@ -18,14 +14,7 @@ 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
|
||||||
- name: Install the latest version of uv
|
uses: Gr1N/setup-poetry@v9
|
||||||
uses: astral-sh/setup-uv@v4
|
|
||||||
with:
|
with:
|
||||||
version: "latest"
|
poetry-version: "1.7.1"
|
||||||
enable-cache: true
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
if: ${{ inputs.install-deps == 'true' }}
|
|
||||||
run: uv sync --frozen
|
|
||||||
shell: bash
|
|
||||||
|
|||||||
+24
-14
@@ -11,7 +11,7 @@ on:
|
|||||||
- nonebot_bison/**
|
- nonebot_bison/**
|
||||||
- tests/**
|
- tests/**
|
||||||
- pyproject.toml
|
- pyproject.toml
|
||||||
- uv.lock
|
- poetry.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
|
||||||
- uv.lock
|
- poetry.lock
|
||||||
- docker.env.prod
|
- docker.env.prod
|
||||||
- .github/**
|
- .github/**
|
||||||
types:
|
types:
|
||||||
@@ -72,13 +72,12 @@ 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 playwright
|
- name: Install prerequisites
|
||||||
run: uv run playwright install
|
run: poetry install
|
||||||
|
|
||||||
- name: Run Pytest
|
- name: Run Pytest
|
||||||
run: uv run pytest --cov-report xml --cov=./nonebot_bison -k 'not compare and not render' -n auto
|
run: poetry 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
|
||||||
@@ -107,13 +106,12 @@ 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 playwright
|
- name: Install prerequisites
|
||||||
run: uv run playwright install
|
run: poetry install
|
||||||
|
|
||||||
- name: Run Pytest
|
- name: Run Pytest
|
||||||
run: uv run pytest --cov-report xml --cov=./nonebot_bison -k 'not compare' -n auto
|
run: poetry 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
|
||||||
@@ -129,6 +127,12 @@ 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
|
||||||
|
|
||||||
@@ -140,7 +144,7 @@ jobs:
|
|||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./docker/Dockerfile
|
file: ./docker/Dockerfile_with_frontend
|
||||||
push: false
|
push: false
|
||||||
load: true
|
load: true
|
||||||
tags: felinae98/nonebot-bison:dummy
|
tags: felinae98/nonebot-bison:dummy
|
||||||
@@ -170,7 +174,7 @@ jobs:
|
|||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./docker/Dockerfile
|
file: ./docker/Dockerfile_with_frontend
|
||||||
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
|
||||||
@@ -184,6 +188,12 @@ 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
|
||||||
|
|
||||||
@@ -205,8 +215,8 @@ jobs:
|
|||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./docker/Dockerfile_without_browser
|
file: ./docker/Dockerfile_with_frontend_sentry
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: felinae98/nonebot-bison:${{ env.GIT_BRANCH_NAME }}-nobrowser
|
tags: felinae98/nonebot-bison:${{ env.GIT_BRANCH_NAME }}-sentry
|
||||||
cache-from: type=gha
|
cache-from: type=gha
|
||||||
cache-to: type=gha,mode=max
|
cache-to: type=gha,mode=max
|
||||||
|
|||||||
@@ -9,12 +9,35 @@ 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
|
||||||
|
|
||||||
@@ -31,7 +54,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./docker/Dockerfile
|
file: ./docker/Dockerfile_with_frontend
|
||||||
push: true
|
push: true
|
||||||
tags: felinae98/nonebot-bison:${{ inputs.dockerTag }}
|
tags: felinae98/nonebot-bison:${{ inputs.dockerTag }}
|
||||||
cache-from: type=gha
|
cache-from: type=gha
|
||||||
@@ -40,9 +63,16 @@ jobs:
|
|||||||
docker-main-sentry:
|
docker-main-sentry:
|
||||||
name: Docker main sentry
|
name: Docker main sentry
|
||||||
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
|
||||||
|
|
||||||
@@ -59,7 +89,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./docker/Dockerfile_without_browser
|
file: ./docker/Dockerfile_with_frontend_sentry
|
||||||
tags: felinae98/nonebot-bison:${{ inputs.dockerTag }}-nobrowser
|
tags: felinae98/nonebot-bison:${{ inputs.dockerTag }}-sentry
|
||||||
cache-from: type=gha
|
cache-from: type=gha
|
||||||
cache-to: type=gha,mode=max
|
cache-to: type=gha,mode=max
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ on:
|
|||||||
- nonebot_bison/**
|
- nonebot_bison/**
|
||||||
- tests/**
|
- tests/**
|
||||||
- pyproject.toml
|
- pyproject.toml
|
||||||
- uv.lock
|
- poetry.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
|
||||||
- uv.lock
|
- poetry.lock
|
||||||
- docker.env.prod
|
- docker.env.prod
|
||||||
- .github/**
|
- .github/**
|
||||||
types:
|
types:
|
||||||
@@ -55,10 +55,7 @@ jobs:
|
|||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
|
|
||||||
- name: Install prerequisites
|
- name: Install prerequisites
|
||||||
run: uv add pydantic==1.10 && uv sync --frozen
|
run: poetry add pydantic@^1.10 && poetry install
|
||||||
|
|
||||||
- name: Install playwright
|
|
||||||
run: uv run playwright install
|
|
||||||
|
|
||||||
- name: Run Pytest
|
- name: Run Pytest
|
||||||
run: uv run pytest -k 'not compare and not render' -n auto
|
run: poetry run pytest -k 'not compare and not render' -n auto
|
||||||
|
|||||||
@@ -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$(uvx --from=toml-cli toml get --toml-path=pyproject.toml project.version)" >> $GITHUB_ENV
|
- run: echo "TAG_NAME=v$(poetry version -s)" >> $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 ${{ env.TAG_NAME }}"
|
git commit -m ":bookmark: Release $(poetry version -s)"
|
||||||
git tag ${{ env.TAG_NAME }}
|
git tag ${{ env.TAG_NAME }}
|
||||||
git push && git push --tags
|
git push && git push --tags
|
||||||
|
|||||||
@@ -54,17 +54,24 @@ jobs:
|
|||||||
|
|
||||||
- name: Publish PyPI and Github
|
- name: Publish PyPI and Github
|
||||||
run: |
|
run: |
|
||||||
uv publish --build -u ${{ secrets.PYPI_USERNAME }} -p ${{ secrets.PYPI_PASSWORD }} || echo "Already pushed to pypi"
|
poetry 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
|
||||||
|
|
||||||
@@ -85,7 +92,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./docker/Dockerfile
|
file: ./docker/Dockerfile_with_frontend
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
felinae98/nonebot-bison:latest
|
felinae98/nonebot-bison:latest
|
||||||
@@ -97,10 +104,10 @@ jobs:
|
|||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./docker/Dockerfile_without_browser
|
file: ./docker/Dockerfile_with_frontend_sentry
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
felinae98/nonebot-bison:${{ env.TAG_NAME }}-nobrowser
|
felinae98/nonebot-bison:${{ env.TAG_NAME }}-sentry
|
||||||
felinae98/nonebot-bison:nobrowser
|
felinae98/nonebot-bison:sentry
|
||||||
cache-from: type=gha
|
cache-from: type=gha
|
||||||
cache-to: type=gha,mode=max
|
cache-to: type=gha,mode=max
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
### Bug 修复
|
### Bug 修复
|
||||||
|
|
||||||
|
- :bug: 修复新版 httpx 中 proxy 不起效的问题 [@suyiiyii](https://github.com/suyiiyii) ([#669](https://github.com/MountainDash/nonebot-bison/pull/669))
|
||||||
- :bug: 修复 cookie 模块 type hint [@suyiiyii](https://github.com/suyiiyii) ([#658](https://github.com/MountainDash/nonebot-bison/pull/658))
|
- :bug: 修复 cookie 模块 type hint [@suyiiyii](https://github.com/suyiiyii) ([#658](https://github.com/MountainDash/nonebot-bison/pull/658))
|
||||||
- :bug: B站转发动态补充 DeletedItem 类型解析 [@AzideCupric](https://github.com/AzideCupric) ([#659](https://github.com/MountainDash/nonebot-bison/pull/659))
|
- :bug: B站转发动态补充 DeletedItem 类型解析 [@AzideCupric](https://github.com/AzideCupric) ([#659](https://github.com/MountainDash/nonebot-bison/pull/659))
|
||||||
- :bug: 小刻食堂cdn使用https [@phidiaLam](https://github.com/phidiaLam) ([#650](https://github.com/MountainDash/nonebot-bison/pull/650))
|
- :bug: 小刻食堂cdn使用https [@phidiaLam](https://github.com/phidiaLam) ([#650](https://github.com/MountainDash/nonebot-bison/pull/650))
|
||||||
|
|||||||
+14
-190
@@ -1,192 +1,16 @@
|
|||||||
# syntax=docker/dockerfile:1.10
|
FROM node:22.11.0 AS frontend
|
||||||
FROM python:3.12-slim AS metadata-stage
|
ADD . /app
|
||||||
|
WORKDIR /app/admin-frontend
|
||||||
WORKDIR /tmp
|
RUN npm install -g pnpm
|
||||||
|
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@9.15.1 --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 python:3.12-slim AS playwright-stage
|
|
||||||
|
|
||||||
WORKDIR /tmp
|
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive \
|
|
||||||
PYTHONUNBUFFERED=1 \
|
|
||||||
TZ=Asia/Shanghai
|
|
||||||
|
|
||||||
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
|
|
||||||
|
|
||||||
|
|
||||||
RUN echo "📦 Installing playwright..." && \
|
|
||||||
uvx playwright install --with-deps chromium && \
|
|
||||||
echo "✅ Playwright installed successfully"
|
|
||||||
|
|
||||||
FROM python:3.12-slim AS production
|
|
||||||
|
|
||||||
|
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/
|
||||||
#ENV UV_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/
|
RUN poetry install --only=main,docker
|
||||||
ENV DEBIAN_FRONTEND=noninteractive \
|
ADD src /app/src
|
||||||
UV_COMPILE_BYTECODE=1 \
|
ADD bot.py /app/
|
||||||
UV_SYSTEM_PYTHON=true \
|
COPY --from=frontend /app/nonebot_bison/admin_page/dist /app/nonebot_bison/admin_page/dist
|
||||||
PYTHONUNBUFFERED=1 \
|
ENV HOST=0.0.0.0
|
||||||
UV_LINK_MODE=copy \
|
CMD ["nb", "run"]
|
||||||
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 --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
|
|
||||||
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
|
|
||||||
|
|
||||||
COPY ./pyproject.toml ./uv.lock ./
|
|
||||||
|
|
||||||
RUN --mount=type=cache,target=/root/.cache/ \
|
|
||||||
--mount=type=cache,target=/root/.uv \
|
|
||||||
echo "📦 Installing bison dependencies..." && \
|
|
||||||
uv pip install --extra=docker --requirement pyproject.toml --no-cache && \
|
|
||||||
echo "✅ Dependencies installed successfully" && \
|
|
||||||
echo "🔔 Cleaning up uv..." && \
|
|
||||||
rm -rf /bin/uv /bin/uvx && \
|
|
||||||
echo "✅ UV cleanup completed"
|
|
||||||
|
|
||||||
COPY --from=metadata-stage /tmp/VERSION /app/VERSION
|
|
||||||
COPY nonebot_bison/ /app/nonebot_bison/
|
|
||||||
COPY --from=frontend-stage /tmp/nonebot_bison/admin_page/dist ./nonebot_bison/admin_page/dist
|
|
||||||
COPY --from=playwright-stage /root/.cache/ms-playwright /root/.cache/ms-playwright
|
|
||||||
|
|
||||||
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 'nb run' >> /app/start.sh && \
|
|
||||||
chmod +x /app/start.sh
|
|
||||||
|
|
||||||
CMD ["/app/start.sh"]
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
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
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
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"]
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
# 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
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# 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
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
# 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@9.15.1 --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 python:3.12-slim AS playwright-stage
|
|
||||||
|
|
||||||
WORKDIR /tmp
|
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive \
|
|
||||||
PYTHONUNBUFFERED=1 \
|
|
||||||
TZ=Asia/Shanghai
|
|
||||||
|
|
||||||
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
|
|
||||||
|
|
||||||
|
|
||||||
RUN echo "📦 Installing playwright..." && \
|
|
||||||
uvx playwright install --with-deps chromium && \
|
|
||||||
echo "✅ Playwright installed successfully"
|
|
||||||
|
|
||||||
FROM python:3.12-slim AS production
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive \
|
|
||||||
UV_COMPILE_BYTECODE=1 \
|
|
||||||
UV_SYSTEM_PYTHON=true \
|
|
||||||
PYTHONUNBUFFERED=1 \
|
|
||||||
UV_LINK_MODE=copy \
|
|
||||||
TZ=Asia/Shanghai \
|
|
||||||
SHELL="/bin/bash"
|
|
||||||
|
|
||||||
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
|
|
||||||
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
|
|
||||||
|
|
||||||
COPY ./pyproject.toml ./uv.lock ./
|
|
||||||
COPY ./docker.env.prod ./.env
|
|
||||||
|
|
||||||
RUN --mount=type=cache,target=/root/.cache/ \
|
|
||||||
--mount=type=cache,target=/root/.uv \
|
|
||||||
echo "📦 Installing bison dependencies..." && \
|
|
||||||
uv pip install --extra=docker --requirement pyproject.toml --no-cache && \
|
|
||||||
echo "✅ Dependencies installed successfully" && \
|
|
||||||
echo "🔔 Cleaning up uv..." && \
|
|
||||||
rm -rf /bin/uv /bin/uvx && \
|
|
||||||
echo "✅ UV cleanup completed"
|
|
||||||
|
|
||||||
COPY --from=metadata-stage /tmp/VERSION /app/VERSION
|
|
||||||
COPY nonebot_bison/ /app/nonebot_bison/
|
|
||||||
COPY --from=frontend-stage /tmp/nonebot_bison/admin_page/dist ./nonebot_bison/admin_page/dist
|
|
||||||
|
|
||||||
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 'nb run' >> /app/start.sh && \
|
|
||||||
chmod +x /app/start.sh
|
|
||||||
|
|
||||||
CMD ["/app/start.sh"]
|
|
||||||
@@ -1,30 +1,33 @@
|
|||||||
|
from collections.abc import Callable
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import json
|
import json
|
||||||
import random
|
import random
|
||||||
from typing import TYPE_CHECKING, ClassVar, TypeVar
|
from typing import TYPE_CHECKING, ClassVar, TypeVar
|
||||||
from typing_extensions import override
|
from typing_extensions import override
|
||||||
|
|
||||||
from httpx import AsyncClient
|
from httpx import AsyncClient, Response
|
||||||
from nonebot import logger, require
|
from nonebot import logger, require
|
||||||
from playwright.async_api import Cookie
|
from playwright.async_api import Cookie
|
||||||
|
|
||||||
|
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.plugin_config import plugin_config
|
from nonebot_bison.config.db_model import Target
|
||||||
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
|
||||||
|
|
||||||
if plugin_config.bison_use_browser:
|
require("nonebot_plugin_htmlrender")
|
||||||
require("nonebot_plugin_htmlrender")
|
from nonebot_plugin_htmlrender import get_browser
|
||||||
from nonebot_plugin_htmlrender import get_browser
|
|
||||||
|
|
||||||
B = TypeVar("B", bound="Bilibili")
|
B = TypeVar("B", bound="Bilibili")
|
||||||
|
|
||||||
|
|
||||||
class BilibiliClientManager(CookieClientManager):
|
class BilibiliClientManager(CookieClientManager):
|
||||||
_default_cookie_cd = timedelta(seconds=120)
|
_default_cookie_cd = timedelta(seconds=120)
|
||||||
|
_current_user_cookie: CookieModel | None = None
|
||||||
|
_site_name = "bilibili.com"
|
||||||
|
|
||||||
async def _get_cookies(self) -> list[Cookie]:
|
async def _get_cookies(self) -> list[Cookie]:
|
||||||
browser = await get_browser()
|
browser = await get_browser()
|
||||||
@@ -59,6 +62,43 @@ class BilibiliClientManager(CookieClientManager):
|
|||||||
)
|
)
|
||||||
return cookie
|
return cookie
|
||||||
|
|
||||||
|
def _generate_hook(self, cookie: CookieModel) -> Callable:
|
||||||
|
"""hook 函数生成器,用于回写请求状态到数据库"""
|
||||||
|
|
||||||
|
async def _response_hook(resp: Response):
|
||||||
|
await resp.aread()
|
||||||
|
if resp.status_code == 200 and "-352" not in resp.text:
|
||||||
|
logger.trace(f"请求成功: {cookie.id} {resp.request.url}")
|
||||||
|
cookie.status = "success"
|
||||||
|
else:
|
||||||
|
logger.warning(f"请求失败: {cookie.id} {resp.request.url}, 状态码: {resp.status_code}")
|
||||||
|
cookie.status = "failed"
|
||||||
|
self._current_user_cookie = None
|
||||||
|
cookie.last_usage = datetime.now()
|
||||||
|
await config.update_cookie(cookie)
|
||||||
|
|
||||||
|
return _response_hook
|
||||||
|
|
||||||
|
async def _get_next_user_cookie(self) -> CookieModel | None:
|
||||||
|
"""选择下一个用户 cookie"""
|
||||||
|
cookies = await config.get_cookie(self._site_name, is_anonymous=False)
|
||||||
|
available_cookies = [cookie for cookie in cookies if cookie.last_usage + cookie.cd < datetime.now()]
|
||||||
|
if not available_cookies:
|
||||||
|
return None
|
||||||
|
cookie = min(available_cookies, key=lambda x: x.last_usage)
|
||||||
|
return cookie
|
||||||
|
|
||||||
|
async def _choose_cookie(self, target: Target | None) -> CookieModel:
|
||||||
|
"""选择 cookie 的具体算法"""
|
||||||
|
if self._current_user_cookie is None:
|
||||||
|
# 若当前没有选定用户 cookie 则尝试获取
|
||||||
|
self._current_user_cookie = await self._get_next_user_cookie()
|
||||||
|
if self._current_user_cookie:
|
||||||
|
# 如果当前有选定的用户 cookie 则直接返回
|
||||||
|
return self._current_user_cookie
|
||||||
|
# 否则返回匿名 cookie
|
||||||
|
return (await config.get_cookie(self._site_name, is_anonymous=True))[0]
|
||||||
|
|
||||||
@override
|
@override
|
||||||
async def refresh_client(self):
|
async def refresh_client(self):
|
||||||
await self._refresh_anonymous_cookie()
|
await self._refresh_anonymous_cookie()
|
||||||
|
|||||||
@@ -124,8 +124,8 @@ class CookieClientManager(ClientManager):
|
|||||||
async def _choose_cookie(self, target: Target | None) -> Cookie:
|
async def _choose_cookie(self, target: Target | None) -> Cookie:
|
||||||
"""选择 cookie 的具体算法"""
|
"""选择 cookie 的具体算法"""
|
||||||
cookies = await config.get_cookie(self._site_name, target)
|
cookies = await config.get_cookie(self._site_name, target)
|
||||||
avaliable_cookies = (cookie for cookie in cookies if cookie.last_usage + cookie.cd < datetime.now())
|
available_cookies = (cookie for cookie in cookies if cookie.last_usage + cookie.cd < datetime.now())
|
||||||
cookie = min(avaliable_cookies, key=lambda x: x.last_usage)
|
cookie = min(available_cookies, key=lambda x: x.last_usage)
|
||||||
return cookie
|
return cookie
|
||||||
|
|
||||||
async def get_client(self, target: Target | None) -> AsyncClient:
|
async def get_client(self, target: Target | None) -> AsyncClient:
|
||||||
@@ -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 # type: ignore[reportArgumentType]
|
site_manager[namespace["name"]] = cls
|
||||||
super().__init__(name, bases, namespace, **kwargs)
|
super().__init__(name, bases, namespace, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Generated
+5067
File diff suppressed because it is too large
Load Diff
+69
-65
@@ -1,34 +1,13 @@
|
|||||||
[project]
|
[tool.poetry]
|
||||||
authors = [{ name = "felinae98", email = "felinae225@qq.com" }]
|
|
||||||
license = { text = "MIT" }
|
|
||||||
requires-python = "<4.0.0,>=3.10"
|
|
||||||
dependencies = [
|
|
||||||
"beautifulsoup4==4.12.3",
|
|
||||||
"feedparser==6.0.11",
|
|
||||||
"httpx==0.27.2",
|
|
||||||
"nonebot2[fastapi]==2.3.3",
|
|
||||||
"nonebot-adapter-onebot==2.4.5",
|
|
||||||
"nonebot-plugin-htmlrender==0.3.5",
|
|
||||||
"nonebot-plugin-datastore==1.3.0",
|
|
||||||
"nonebot-plugin-apscheduler==0.5.0",
|
|
||||||
"nonebot-plugin-send-anything-anywhere==0.7.1",
|
|
||||||
"pillow==11.0.0",
|
|
||||||
"pyjwt==2.9.0",
|
|
||||||
"python-socketio==5.11.4",
|
|
||||||
"tinydb==4.8.0",
|
|
||||||
"qrcode==7.4.2",
|
|
||||||
"Pydantic==2.9.2",
|
|
||||||
"lxml==5.3.0",
|
|
||||||
"yarl==1.11.1",
|
|
||||||
"hishel==0.0.30",
|
|
||||||
"expiringdictx==1.1.0",
|
|
||||||
"rapidfuzz==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",
|
||||||
@@ -41,49 +20,69 @@ classifiers = [
|
|||||||
"License :: OSI Approved :: MIT License",
|
"License :: OSI Approved :: MIT License",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[tool.poetry.dependencies]
|
||||||
homepage = "https://github.com/felinae98/nonebot-bison"
|
python = ">=3.10,<4.0.0"
|
||||||
|
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"
|
||||||
|
|
||||||
[project.entry-points.nb_scripts]
|
[tool.poetry.group.dev.dependencies]
|
||||||
|
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==0.13.13",
|
|
||||||
"nonemoji==0.1.4",
|
|
||||||
"nb-cli==1.4.2",
|
|
||||||
"pre-commit==4.0.1",
|
|
||||||
"ruff==0.8.2",
|
|
||||||
]
|
|
||||||
test = [
|
|
||||||
"flaky==3.8.1",
|
|
||||||
"nonebug==0.3.7",
|
|
||||||
"pytz==2024.2",
|
|
||||||
"nonebug-saa==0.4.1",
|
|
||||||
"pytest==8.3.3",
|
|
||||||
"pytest-asyncio==0.24.0",
|
|
||||||
"pytest-cov==6.0.0",
|
|
||||||
"pytest-mock==3.14.0",
|
|
||||||
"pytest-xdist[psutil]==3.6.1",
|
|
||||||
"respx==0.21.1",
|
|
||||||
"freezegun==1.5.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[project.optional-dependencies]
|
|
||||||
docker = [
|
|
||||||
"nb-cli==1.4.2",
|
|
||||||
"nonebot2[aiohttp,fastapi]==2.3.3",
|
|
||||||
"nonebot-adapter-red==0.9.0",
|
|
||||||
"nonebot-adapter-qq==1.5.1",
|
|
||||||
"poetry-core==1.9.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[tool.uv]
|
|
||||||
default-groups = ["dev", "test"]
|
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["pdm-backend"]
|
requires = ["poetry-core>=1.9.0"]
|
||||||
build-backend = "pdm.backend"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
markers = [
|
markers = [
|
||||||
@@ -158,3 +157,8 @@ executionEnvironments = [
|
|||||||
{ root = "./" },
|
{ root = "./" },
|
||||||
]
|
]
|
||||||
defineConstant = { PYDANTIC_V2 = true }
|
defineConstant = { PYDANTIC_V2 = true }
|
||||||
|
|
||||||
|
[[tool.poetry.source]]
|
||||||
|
name = "offical-source"
|
||||||
|
url = "https://pypi.org/simple/"
|
||||||
|
priority = "primary"
|
||||||
|
|||||||
Reference in New Issue
Block a user