Skip to content

Commit

Permalink
♻️ seperate BilibiliClient
Browse files Browse the repository at this point in the history
  • Loading branch information
felinae98 committed Mar 10, 2024
1 parent ec35b15 commit 64bd6ec
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 331 deletions.
50 changes: 30 additions & 20 deletions nonebot_bison/platform/bilibili.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,47 @@
from .platform import NewMessage, StatusChange, CategoryNotSupport, CategoryNotRecognize


class BaseSchedConf(ABC, SchedulerConfig):
schedule_type = "interval"
_client_refresh_time = datetime(year=2000, month=1, day=1) # an expired time
class BilibiliClient:
_client: AsyncClient
_refresh_time: datetime
cookie_expire_time = timedelta(hours=5)

bili_http_client = http_client()

def __init__(self):
super().__init__()
self.default_http_client = self.bili_http_client
def __init__(self) -> None:
self._client = http_client()
self._refresh_time = datetime(year=2000, month=1, day=1) # an expired time

@classmethod
async def _init_session(cls):
res = await cls.bili_http_client.get("https://www.bilibili.com/")
async def _init_session(self):
res = await self._client.get("https://www.bilibili.com/")
if res.status_code != 200:
logger.warning("unable to refresh temp cookie")
else:
cls._client_refresh_time = datetime.now()
self._refresh_time = datetime.now()

@classmethod
async def _refresh_client(cls):
if datetime.now() - cls._client_refresh_time > cls.cookie_expire_time:
await cls._init_session()
async def _refresh_client(self):
if datetime.now() - self._refresh_time > self.cookie_expire_time:
await self._init_session()

async def get_client(self, target: Target) -> AsyncClient:
async def get_client(self) -> AsyncClient:
await self._refresh_client()
return await super().get_client(target)
return self._client


bilibili_client = BilibiliClient()


class BaseSchedConf(ABC, SchedulerConfig):
schedule_type = "interval"
bilibili_client: BilibiliClient

def __init__(self):
super().__init__()
self.bilibili_client = bilibili_client

async def get_client(self, _: Target) -> AsyncClient:
return await self.bilibili_client.get_client()

async def get_query_name_client(self) -> AsyncClient:
await self._refresh_client()
return await super().get_query_name_client()
return await self.bilibili_client.get_client()


class BilibiliSchedConf(BaseSchedConf):
Expand Down
312 changes: 1 addition & 311 deletions tests/platforms/test_bilibili_live.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
from copy import deepcopy

import respx
import pytest
from nonebug.app import App
from httpx import Response, AsyncClient

from .utils import get_json
from httpx import AsyncClient


@pytest.fixture()
Expand All @@ -24,308 +19,3 @@ def dummy_only_open_user_subinfo(app: App):

user = TargetQQGroup(group_id=123)
return UserSubInfo(user=user, categories=[1], tags=[])


@pytest.mark.asyncio
async def test_http_client_equal(app: App):
from nonebot_bison.types import Target
from nonebot_bison.utils import ProcessContext
from nonebot_bison.platform import platform_manager

empty_target = Target("0")

bilibili = platform_manager["bilibili"](ProcessContext(), AsyncClient())
bilibili_live = platform_manager["bilibili-live"](ProcessContext(), AsyncClient())

bilibili_scheduler = bilibili.scheduler()
bilibili_live_scheduler = bilibili_live.scheduler()

await bilibili_scheduler._init_session() # type: ignore
await bilibili_live_scheduler._init_session() # type: ignore

assert bilibili_scheduler.default_http_client == bilibili_live_scheduler.default_http_client

assert await bilibili_scheduler.get_client(empty_target) == await bilibili_live_scheduler.get_client(empty_target)
assert await bilibili_live_scheduler.get_client(empty_target) == bilibili_live_scheduler.default_http_client

assert await bilibili_scheduler.get_query_name_client() == await bilibili_live_scheduler.get_query_name_client()
assert await bilibili_scheduler.get_query_name_client() == bilibili_live_scheduler.default_http_client


@pytest.mark.asyncio
@respx.mock
async def test_fetch_bililive_no_room(bili_live, dummy_only_open_user_subinfo):
from nonebot_bison.types import Target, SubUnit

mock_bili_live_status = get_json("bili_live_status.json")
mock_bili_live_status["data"] = {}
bili_live_router = respx.get("https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids?uids[]=13164144")
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))

bilibili_main_page_router = respx.get("https://www.bilibili.com/")
bilibili_main_page_router.mock(return_value=Response(200))

target = Target("13164144")
res = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_open_user_subinfo]))])
assert bili_live_router.call_count == 1
assert len(res) == 0


@pytest.mark.asyncio
@respx.mock
async def test_fetch_first_live(bili_live, dummy_only_open_user_subinfo):
from nonebot_bison.types import Target, SubUnit

mock_bili_live_status = get_json("bili_live_status.json")
empty_bili_live_status = deepcopy(mock_bili_live_status)
empty_bili_live_status["data"] = {}
bili_live_router = respx.get("https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids?uids[]=13164144")
bili_live_router.mock(return_value=Response(200, json=empty_bili_live_status))

bilibili_main_page_router = respx.get("https://www.bilibili.com/")
bilibili_main_page_router.mock(return_value=Response(200))

target = Target("13164144")
res = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_open_user_subinfo]))])
assert bili_live_router.call_count == 1
assert len(res) == 0

mock_bili_live_status["data"][target]["live_status"] = 1
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res2 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_open_user_subinfo]))])
assert bili_live_router.call_count == 2
assert len(res2) == 1
post = res2[0][1][0]
assert post.target_type == "Bilibili直播"
assert post.text == "[开播] 【Zc】从0挑战到15肉鸽!目前10难度"
assert post.url == "https://live.bilibili.com/3044248"
assert post.target_name == "魔法Zc目录 其他单机"
assert post.pics == ["https://i0.hdslb.com/bfs/live/new_room_cover/fd357f0f3cbbb48e9acfbcda616b946c2454c56c.jpg"]
assert post.compress is True


@pytest.mark.asyncio
@respx.mock
async def test_fetch_bililive_only_live_open(bili_live, dummy_only_open_user_subinfo):
from nonebot_bison.types import Target, SubUnit

mock_bili_live_status = get_json("bili_live_status.json")

bili_live_router = respx.get("https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids?uids[]=13164144")
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))

bilibili_main_page_router = respx.get("https://www.bilibili.com/")
bilibili_main_page_router.mock(return_value=Response(200))

target = Target("13164144")
res = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_open_user_subinfo]))])
assert bili_live_router.call_count == 1
assert len(res[0][1]) == 0
# 直播状态更新-上播
mock_bili_live_status["data"][target]["live_status"] = 1
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res2 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_open_user_subinfo]))])
post = res2[0][1][0]
assert post.target_type == "Bilibili直播"
assert post.text == "[开播] 【Zc】从0挑战到15肉鸽!目前10难度"
assert post.url == "https://live.bilibili.com/3044248"
assert post.target_name == "魔法Zc目录 其他单机"
assert post.pics == ["https://i0.hdslb.com/bfs/live/new_room_cover/fd357f0f3cbbb48e9acfbcda616b946c2454c56c.jpg"]
assert post.compress is True
# 标题变更
mock_bili_live_status["data"][target]["title"] = "【Zc】从0挑战到15肉鸽!目前11难度"
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res3 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_open_user_subinfo]))])
assert bili_live_router.call_count == 3
assert len(res3[0][1]) == 0
# 直播状态更新-下播
mock_bili_live_status["data"][target]["live_status"] = 0
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res4 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_open_user_subinfo]))])
assert bili_live_router.call_count == 4
assert len(res4[0][1]) == 0


@pytest.fixture()
def dummy_only_title_user_subinfo(app: App):
from nonebot_plugin_saa import TargetQQGroup

from nonebot_bison.types import UserSubInfo

user = TargetQQGroup(group_id=123)
return UserSubInfo(user=user, categories=[2], tags=[])


@pytest.mark.asyncio()
@respx.mock
async def test_fetch_bililive_only_title_change(bili_live, dummy_only_title_user_subinfo):
from nonebot_bison.types import Target, SubUnit

mock_bili_live_status = get_json("bili_live_status.json")
target = Target("13164144")

bili_live_router = respx.get("https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids?uids[]=13164144")
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))

bilibili_main_page_router = respx.get("https://www.bilibili.com/")
bilibili_main_page_router.mock(return_value=Response(200))

res = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_title_user_subinfo]))])
assert bili_live_router.call_count == 1
assert len(res) == 0
# 未开播前标题变更
mock_bili_live_status["data"][target]["title"] = "【Zc】从0挑战到15肉鸽!目前11难度"
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res0 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_title_user_subinfo]))])
assert bili_live_router.call_count == 2
assert len(res0) == 0
# 直播状态更新-上播
mock_bili_live_status["data"][target]["live_status"] = 1
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res2 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_title_user_subinfo]))])
assert bili_live_router.call_count == 3
assert len(res2[0][1]) == 0
# 标题变更
mock_bili_live_status["data"][target]["title"] = "【Zc】从0挑战到15肉鸽!目前12难度"
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res3 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_title_user_subinfo]))])
post = res3[0][1][0]
assert post.target_type == "Bilibili直播"
assert post.text == "[标题更新] 【Zc】从0挑战到15肉鸽!目前12难度"
assert post.url == "https://live.bilibili.com/3044248"
assert post.target_name == "魔法Zc目录 其他单机"
assert post.pics == ["https://i0.hdslb.com/bfs/live-key-frame/keyframe10170435000003044248mwowx0.jpg"]
assert post.compress is True
# 直播状态更新-下播
mock_bili_live_status["data"][target]["live_status"] = 0
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res4 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_title_user_subinfo]))])
assert bili_live_router.call_count == 5
assert len(res4[0][1]) == 0


@pytest.fixture()
def dummy_only_close_user_subinfo(app: App):
from nonebot_plugin_saa import TargetQQGroup

from nonebot_bison.types import UserSubInfo

user = TargetQQGroup(group_id=123)
return UserSubInfo(user=user, categories=[3], tags=[])


@pytest.mark.asyncio
@respx.mock
async def test_fetch_bililive_only_close(bili_live, dummy_only_close_user_subinfo):
from nonebot_bison.types import Target, SubUnit

mock_bili_live_status = get_json("bili_live_status.json")
target = Target("13164144")

bili_live_router = respx.get("https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids?uids[]=13164144")
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))

bilibili_main_page_router = respx.get("https://www.bilibili.com/")
bilibili_main_page_router.mock(return_value=Response(200))

res = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_close_user_subinfo]))])
assert bili_live_router.call_count == 1
assert len(res) == 0
# 未开播前标题变更
mock_bili_live_status["data"][target]["title"] = "【Zc】从0挑战到15肉鸽!目前11难度"
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res0 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_close_user_subinfo]))])
assert bili_live_router.call_count == 2
assert len(res0) == 0
# 直播状态更新-上播
mock_bili_live_status["data"][target]["live_status"] = 1
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res2 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_close_user_subinfo]))])
assert bili_live_router.call_count == 3
assert len(res2[0][1]) == 0
# 标题变更
mock_bili_live_status["data"][target]["title"] = "【Zc】从0挑战到15肉鸽!目前12难度"
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res3 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_close_user_subinfo]))])
assert bili_live_router.call_count == 4
assert len(res3[0][1]) == 0
# 直播状态更新-下播
mock_bili_live_status["data"][target]["live_status"] = 0
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res4 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_close_user_subinfo]))])
assert bili_live_router.call_count == 5
post = res4[0][1][0]
assert post.target_type == "Bilibili直播"
assert post.text == "[下播] 【Zc】从0挑战到15肉鸽!目前12难度"
assert post.url == "https://live.bilibili.com/3044248"
assert post.target_name == "魔法Zc目录 其他单机"
assert post.pics == ["https://i0.hdslb.com/bfs/live-key-frame/keyframe10170435000003044248mwowx0.jpg"]
assert post.compress is True


@pytest.fixture()
def dummy_bililive_user_subinfo(app: App):
from nonebot_plugin_saa import TargetQQGroup

from nonebot_bison.types import UserSubInfo

user = TargetQQGroup(group_id=123)
return UserSubInfo(user=user, categories=[1, 2, 3], tags=[])


@pytest.mark.asyncio
@respx.mock
async def test_fetch_bililive_combo(bili_live, dummy_bililive_user_subinfo):
from nonebot_bison.types import Target, SubUnit

mock_bili_live_status = get_json("bili_live_status.json")
target = Target("13164144")

bili_live_router = respx.get("https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids?uids[]=13164144")
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))

bilibili_main_page_router = respx.get("https://www.bilibili.com/")
bilibili_main_page_router.mock(return_value=Response(200))

res = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_bililive_user_subinfo]))])
assert bili_live_router.call_count == 1
assert len(res) == 0
# 未开播前标题变更
mock_bili_live_status["data"][target]["title"] = "【Zc】从0挑战到15肉鸽!目前11难度"
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res0 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_bililive_user_subinfo]))])
assert bili_live_router.call_count == 2
assert len(res0) == 0
# 直播状态更新-上播
mock_bili_live_status["data"][target]["live_status"] = 1
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res2 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_bililive_user_subinfo]))])
post2 = res2[0][1][0]
assert post2.target_type == "Bilibili直播"
assert post2.text == "[开播] 【Zc】从0挑战到15肉鸽!目前11难度"
assert post2.url == "https://live.bilibili.com/3044248"
assert post2.target_name == "魔法Zc目录 其他单机"
assert post2.pics == ["https://i0.hdslb.com/bfs/live/new_room_cover/fd357f0f3cbbb48e9acfbcda616b946c2454c56c.jpg"]
assert post2.compress is True
# 标题变更
mock_bili_live_status["data"][target]["title"] = "【Zc】从0挑战到15肉鸽!目前12难度"
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res3 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_bililive_user_subinfo]))])
post3 = res3[0][1][0]
assert post3.target_type == "Bilibili直播"
assert post3.text == "[标题更新] 【Zc】从0挑战到15肉鸽!目前12难度"
assert post3.url == "https://live.bilibili.com/3044248"
assert post3.target_name == "魔法Zc目录 其他单机"
assert post3.pics == ["https://i0.hdslb.com/bfs/live-key-frame/keyframe10170435000003044248mwowx0.jpg"]
assert post3.compress is True
# 直播状态更新-下播
mock_bili_live_status["data"][target]["live_status"] = 0
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res4 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_bililive_user_subinfo]))])
post4 = res4[0][1][0]
assert post4.target_type == "Bilibili直播"
assert post4.text == "[下播] 【Zc】从0挑战到15肉鸽!目前12难度"
assert post4.url == "https://live.bilibili.com/3044248"
assert post4.target_name == "魔法Zc目录 其他单机"
assert post4.pics == ["https://i0.hdslb.com/bfs/live-key-frame/keyframe10170435000003044248mwowx0.jpg"]
assert post4.compress is True

0 comments on commit 64bd6ec

Please sign in to comment.