mirror of
				https://github.com/suyiiyii/nonebot-bison.git
				synced 2025-11-04 05:24:53 +08:00 
			
		
		
		
	Compare commits
	
		
			7 Commits
		
	
	
		
			d6e7acf45f
			...
			1031e9f9a5
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 1031e9f9a5 | |||
| 57e68ac0b9 | |||
| 29a807df5a | |||
| 59846642cc | |||
| 
						 | 
					e45bf03e49 | ||
| 3421e3ac5e | |||
| 5a7396bada | 
@ -9,6 +9,7 @@
 | 
			
		||||
 | 
			
		||||
### 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: 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))
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
FROM node:22.11.0 as frontend
 | 
			
		||||
FROM node:22.11.0 AS frontend
 | 
			
		||||
ADD . /app
 | 
			
		||||
WORKDIR /app/admin-frontend
 | 
			
		||||
RUN npm install -g pnpm
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
# syntax=docker/dockerfile:1.10
 | 
			
		||||
FROM python:3.11-slim-bullseye as base
 | 
			
		||||
FROM python:3.11-slim-bullseye AS base
 | 
			
		||||
 | 
			
		||||
FROM base as builder
 | 
			
		||||
FROM base AS builder
 | 
			
		||||
 | 
			
		||||
ENV PYTHONFAULTHANDLER=1 \
 | 
			
		||||
  PYTHONUNBUFFERED=1 \
 | 
			
		||||
@ -12,7 +12,6 @@ ENV PYTHONFAULTHANDLER=1 \
 | 
			
		||||
  POETRY_NO_INTERACTION=1 \
 | 
			
		||||
  POETRY_VIRTUALENVS_CREATE=false \
 | 
			
		||||
  PATH="$PATH:/runtime/bin" \
 | 
			
		||||
  PYTHONPATH="$PYTHONPATH:/runtime/lib/python3.10/site-packages" \
 | 
			
		||||
  # Versions:
 | 
			
		||||
  POETRY_VERSION=1.7.1
 | 
			
		||||
RUN apt-get update && apt-get install -y build-essential unzip wget python-dev git
 | 
			
		||||
@ -25,7 +24,7 @@ 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
 | 
			
		||||
FROM base AS runtime
 | 
			
		||||
 | 
			
		||||
WORKDIR /app
 | 
			
		||||
RUN --mount=type=cache,target=/var/cache/apt \
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
# syntax=docker/dockerfile:1.10
 | 
			
		||||
FROM python:3.11-slim-bullseye as base
 | 
			
		||||
FROM python:3.11-slim-bullseye AS base
 | 
			
		||||
 | 
			
		||||
FROM base as builder
 | 
			
		||||
FROM base AS builder
 | 
			
		||||
 | 
			
		||||
ENV PYTHONFAULTHANDLER=1 \
 | 
			
		||||
  PYTHONUNBUFFERED=1 \
 | 
			
		||||
@ -12,7 +12,6 @@ ENV PYTHONFAULTHANDLER=1 \
 | 
			
		||||
  POETRY_NO_INTERACTION=1 \
 | 
			
		||||
  POETRY_VIRTUALENVS_CREATE=false \
 | 
			
		||||
  PATH="$PATH:/runtime/bin" \
 | 
			
		||||
  PYTHONPATH="$PYTHONPATH:/runtime/lib/python3.10/site-packages" \
 | 
			
		||||
  # Versions:
 | 
			
		||||
  POETRY_VERSION=1.7.1
 | 
			
		||||
RUN apt-get update && apt-get install -y build-essential unzip wget python3-dev git
 | 
			
		||||
@ -25,7 +24,7 @@ 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
 | 
			
		||||
FROM base AS runtime
 | 
			
		||||
 | 
			
		||||
WORKDIR /app
 | 
			
		||||
RUN --mount=type=cache,target=/var/cache/apt \
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,17 @@
 | 
			
		||||
from collections.abc import Callable
 | 
			
		||||
from datetime import datetime, timedelta
 | 
			
		||||
import json
 | 
			
		||||
import random
 | 
			
		||||
from typing import TYPE_CHECKING, ClassVar, TypeVar
 | 
			
		||||
from typing_extensions import override
 | 
			
		||||
 | 
			
		||||
from httpx import AsyncClient
 | 
			
		||||
from httpx import AsyncClient, Response
 | 
			
		||||
from nonebot import logger, require
 | 
			
		||||
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 Target
 | 
			
		||||
from nonebot_bison.utils import Site, http_client
 | 
			
		||||
from nonebot_bison.utils.site import CookieClientManager
 | 
			
		||||
 | 
			
		||||
@ -23,6 +26,8 @@ B = TypeVar("B", bound="Bilibili")
 | 
			
		||||
 | 
			
		||||
class BilibiliClientManager(CookieClientManager):
 | 
			
		||||
    _default_cookie_cd = timedelta(seconds=120)
 | 
			
		||||
    _current_user_cookie: CookieModel | None = None
 | 
			
		||||
    _site_name = "bilibili.com"
 | 
			
		||||
 | 
			
		||||
    async def _get_cookies(self) -> list[Cookie]:
 | 
			
		||||
        browser = await get_browser()
 | 
			
		||||
@ -57,6 +62,43 @@ class BilibiliClientManager(CookieClientManager):
 | 
			
		||||
        )
 | 
			
		||||
        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
 | 
			
		||||
    async def refresh_client(self):
 | 
			
		||||
        await self._refresh_anonymous_cookie()
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import httpx
 | 
			
		||||
from nonebot_bison.plugin_config import plugin_config
 | 
			
		||||
 | 
			
		||||
http_args = {
 | 
			
		||||
    "proxies": plugin_config.bison_proxy or None,
 | 
			
		||||
    "proxy": plugin_config.bison_proxy or None,
 | 
			
		||||
}
 | 
			
		||||
http_headers = {"user-agent": plugin_config.bison_ua}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -124,8 +124,8 @@ class CookieClientManager(ClientManager):
 | 
			
		||||
    async def _choose_cookie(self, target: Target | None) -> Cookie:
 | 
			
		||||
        """选择 cookie 的具体算法"""
 | 
			
		||||
        cookies = await config.get_cookie(self._site_name, target)
 | 
			
		||||
        avaliable_cookies = (cookie for cookie in cookies if cookie.last_usage + cookie.cd < datetime.now())
 | 
			
		||||
        cookie = min(avaliable_cookies, key=lambda x: x.last_usage)
 | 
			
		||||
        available_cookies = (cookie for cookie in cookies if cookie.last_usage + cookie.cd < datetime.now())
 | 
			
		||||
        cookie = min(available_cookies, key=lambda x: x.last_usage)
 | 
			
		||||
        return cookie
 | 
			
		||||
 | 
			
		||||
    async def get_client(self, target: Target | None) -> AsyncClient:
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user