🐛 修复bililive订阅没有直播间的用户报错的问题

This commit is contained in:
Azide 2023-06-19 02:14:53 +08:00 committed by felinae98
parent 147f858a31
commit 4f7a3ebfbe
2 changed files with 93 additions and 20 deletions

View File

@ -297,6 +297,21 @@ class Bilibililive(StatusChange):
return None
return res_data["data"]["card"]["name"]
def gen_empty_info(self, uid: int) -> Info:
"""返回一个空的Info用于该用户没有直播间的情况"""
return Bilibililive.Info(
title="",
room_id=0,
uid=uid,
live_time=0,
live_status=Bilibililive.LiveStatus.OFF,
area_v2_name="",
uname="",
face="",
cover_from_user="",
keyframe="",
)
async def get_status(self, target: Target) -> Info:
params = {"uids[]": target}
# https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/live/info.md#批量查询直播间状态
@ -307,41 +322,40 @@ class Bilibililive(StatusChange):
)
res_dict = res.json()
if res_dict["code"] == 0:
data = res_dict["data"][target]
self.Info.update_forward_refs()
info = self.Info.parse_obj(data)
return info
else:
if res_dict["code"] != 0:
raise self.FetchError()
data = res_dict.get("data")
if not data:
return self.gen_empty_info(uid=int(target))
room_data = data[target]
return self.Info.parse_obj(room_data)
def compare_status(
self, _: Target, old_status: Info, new_status: Info
) -> list[RawPost]:
action = Bilibililive.LiveAction
match new_status.get_live_action(old_status):
case action.TURN_ON:
current_status = deepcopy(new_status)
current_status.category = Category(1)
return [current_status]
return self._gen_current_status(new_status, 1)
case action.TITLE_UPDATE:
current_status = deepcopy(new_status)
current_status.category = Category(2)
return [current_status]
return self._gen_current_status(new_status, 2)
case action.TURN_OFF:
current_status = deepcopy(new_status)
current_status.category = Category(3)
return [current_status]
return self._gen_current_status(new_status, 3)
case _:
return []
def _gen_current_status(self, new_status: Info, category: Category):
current_status = deepcopy(new_status)
current_status.category = Category(category)
return [current_status]
def get_category(self, status: Info) -> Category:
assert status.category != Category(0)
return status.category
async def parse(self, raw_post: Info) -> Post:
url = "https://live.bilibili.com/{}".format(raw_post.room_id)
url = f"https://live.bilibili.com/{raw_post.room_id}"
pic = (
[raw_post.cover]
if raw_post.category == Category(1)
@ -387,11 +401,11 @@ class BilibiliBangumi(StatusChange):
if re.match(r"\d+", target_string):
return Target(target_string)
elif m := re.match(r"md(\d+)", target_string):
return Target(m.group(1))
return Target(m[1])
elif m := re.match(
r"(?:https?://)?www\.bilibili\.com/bangumi/media/md(\d+)", target_string
):
return Target(m.group(1))
return Target(m[1])
raise cls.ParseTargetException()
async def get_status(self, target: Target):
@ -441,3 +455,6 @@ class BilibiliBangumi(StatusChange):
target_name=target_name,
compress=True,
)
Bilibililive.Info.update_forward_refs()

View File

@ -1,3 +1,5 @@
from copy import deepcopy
import pytest
import respx
from httpx import AsyncClient, Response
@ -24,6 +26,60 @@ def dummy_only_open_user_subinfo(app: App):
return UserSubInfo(user=user, categories=[1], tags=[])
@pytest.mark.asyncio
@respx.mock
async def test_fetch_bililive_no_room(bili_live, dummy_only_open_user_subinfo):
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 = "13164144"
res = await bili_live.fetch_new_post(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):
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 = "13164144"
res = await bili_live.fetch_new_post(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.fetch_new_post(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 == True
@pytest.mark.asyncio
@respx.mock
async def test_fetch_bililive_only_live_open(bili_live, dummy_only_open_user_subinfo):
@ -40,7 +96,7 @@ async def test_fetch_bililive_only_live_open(bili_live, dummy_only_open_user_sub
target = "13164144"
res = await bili_live.fetch_new_post(target, [dummy_only_open_user_subinfo])
assert bili_live_router.call_count == 1
assert len(res) == 0
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))