From 1c63384082f45a176012edc7d1f96abf15a72cc9 Mon Sep 17 00:00:00 2001 From: HibiKier <775757368@qq.com> Date: Sun, 16 Apr 2023 03:47:09 +0800 Subject: [PATCH] =?UTF-8?q?`BilibiliSub`=E7=9A=84=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=94=B9=E4=B8=BA=E5=AD=97=E7=AC=A6=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + plugins/bilibili_sub/__init__.py | 15 ++- plugins/bilibili_sub/data_source.py | 153 ++++++++++++++-------------- plugins/bilibili_sub/model.py | 12 ++- plugins/bilibili_sub/utils.py | 23 +++-- 5 files changed, 110 insertions(+), 95 deletions(-) diff --git a/README.md b/README.md index d79fd8d0..bbda4355 100644 --- a/README.md +++ b/README.md @@ -335,6 +335,8 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能 * 修复开箱更新未登录时没有停止更新 * 修复更新色图问题 +* fix bug [@pull/1368](https://github.com/HibiKier/zhenxun_bot/pull/1368) +* `BilibiliSub`的部分字段改为字符串 ### 2023/4/5 diff --git a/plugins/bilibili_sub/__init__.py b/plugins/bilibili_sub/__init__.py index e936addb..6f258626 100755 --- a/plugins/bilibili_sub/__init__.py +++ b/plugins/bilibili_sub/__init__.py @@ -78,7 +78,7 @@ show_sub_info = on_regex("^查看订阅$", priority=5, block=True) driver: Driver = nonebot.get_driver() -sub_manager: Optional[SubManager] = None +sub_manager: SubManager @driver.on_startup @@ -99,7 +99,7 @@ async def _(event: MessageEvent, state: T_State, arg: Message = CommandArg()): if not await LevelUser.check_level( event.user_id, event.group_id, - Config.get_config("bilibili_sub", "GROUP_BILIBILI_SUB_LEVEL"), + Config.get_config("bilibili_sub", "GROUP_BILIBILI_SUB_LEVEL"), # type: ignore ): await add_sub.finish( f"您的权限不足,群内订阅的需要 {Config.get_config('bilibili_sub', 'GROUP_BILIBILI_SUB_LEVEL')} 级权限..", @@ -120,10 +120,10 @@ async def _(event: MessageEvent, state: T_State, arg: Message = CommandArg()): if sub_type in ["season", "动漫", "番剧"]: rst = "*以为您找到以下番剧,请输入Id选择:*\n" state["season_data"] = await get_media_id(id_) - if len(state["season_data"]) == 0: + if len(state["season_data"]) == 0: # type: ignore await add_sub.finish(f"未找到番剧:{msg}") - for i, x in enumerate(state["season_data"]): - rst += f'{i + 1}.{state["season_data"][x]["title"]}\n----------\n' + for i, x in enumerate(state["season_data"]): # type: ignore + rst += f'{i + 1}.{state["season_data"][x]["title"]}\n----------\n' # type: ignore await add_sub.send("\n".join(rst.split("\n")[:-1])) else: await add_sub.finish("Id 必须为全数字!") @@ -146,7 +146,6 @@ async def _( if not is_number(id_) or int(id_) < 1 or int(id_) > len(season_data): await add_sub.reject_arg("id", "Id必须为数字且在范围内!请重新输入...") id_ = season_data[int(id_) - 1]["media_id"] - id_ = int(id_) if sub_type in ["主播", "直播"]: await add_sub.send(await add_live_sub(id_, sub_user)) elif sub_type.lower() in ["up", "用户"]: @@ -243,10 +242,10 @@ async def _(): if sub: logger.debug(f"Bilibili订阅开始检测:{sub.sub_id}") rst = await get_sub_status(sub.sub_id, sub.sub_type) - await send_sub_msg(rst, sub, bot) + await send_sub_msg(rst or "", sub, bot) # type: ignore if sub.sub_type == "live": rst = await get_sub_status(sub.sub_id, "up") - await send_sub_msg(rst, sub, bot) + await send_sub_msg(rst or "", sub, bot) # type: ignore # except Exception as e: # logger.error(f"B站订阅推送发生错误 sub_id:{sub.sub_id if sub else 0} {type(e)}:{e}") diff --git a/plugins/bilibili_sub/data_source.py b/plugins/bilibili_sub/data_source.py index a8175257..5e393862 100755 --- a/plugins/bilibili_sub/data_source.py +++ b/plugins/bilibili_sub/data_source.py @@ -30,7 +30,7 @@ DYNAMIC_PATH.mkdir(exist_ok=True, parents=True) resources_manager.add_temp_dir(DYNAMIC_PATH) -async def add_live_sub(live_id: int, sub_user: str) -> str: +async def add_live_sub(live_id: str, sub_user: str) -> str: """ 添加直播订阅 :param live_id: 直播房间号 @@ -57,14 +57,16 @@ async def add_live_sub(live_id: int, sub_user: str) -> str: live_status=live_status, ): await _get_up_status(room_id) - uname = (await BilibiliSub.get_or_none(sub_id=room_id)).uname - return ( - "已成功订阅主播:\n" - f"\ttitle:{title}\n" - f"\tname: {uname}\n" - f"\tlive_id:{room_id}\n" - f"\tuid:{uid}" - ) + if data := await BilibiliSub.get_or_none(sub_id=room_id): + uname = data.uname + return ( + "已成功订阅主播:\n" + f"\ttitle:{title}\n" + f"\tname: {uname}\n" + f"\tlive_id:{room_id}\n" + f"\tuid:{uid}" + ) + return "添加订阅失败..." else: return "添加订阅失败..." except Exception as e: @@ -72,7 +74,7 @@ async def add_live_sub(live_id: int, sub_user: str) -> str: return "添加订阅失败..." -async def add_up_sub(uid: int, sub_user: str) -> str: +async def add_up_sub(uid: str, sub_user: str) -> str: """ 添加订阅 UP :param uid: UP uid @@ -86,12 +88,12 @@ async def add_up_sub(uid: int, sub_user: str) -> str: return f"未找到UpId:{uid} 的信息,请检查Id是否正确" uname = user_info["name"] """bilibili_api.user库中User类的get_dynamics改为bilireq.dynamic库的get_user_dynamics方法""" - dynamic_info = await dynamic.get_user_dynamics(uid) + dynamic_info = await dynamic.get_user_dynamics(int(uid)) dynamic_upload_time = 0 if dynamic_info.get("cards"): dynamic_upload_time = dynamic_info["cards"][0]["desc"]["timestamp"] """bilibili_api.user库中User类的get_videos改为bilireq.user库的get_videos方法""" - video_info = await get_videos(uid) + video_info = await get_videos(int(uid)) latest_video_created = 0 if video_info["list"].get("vlist"): latest_video_created = video_info["list"]["vlist"][0]["created"] @@ -99,7 +101,7 @@ async def add_up_sub(uid: int, sub_user: str) -> str: uid, "up", sub_user, - uid=uid, + uid=int(uid), uname=uname, dynamic_upload_time=dynamic_upload_time, latest_video_created=latest_video_created, @@ -112,7 +114,7 @@ async def add_up_sub(uid: int, sub_user: str) -> str: return "添加订阅失败..." -async def add_season_sub(media_id: int, sub_user: str) -> str: +async def add_season_sub(media_id: str, sub_user: str) -> str: """ 添加订阅 UP :param media_id: 番剧 media_id @@ -159,7 +161,7 @@ async def delete_sub(sub_id: str, sub_user: str) -> str: return f"取消订阅:{sub_id} 失败,请检查是否订阅过该Id...." -async def get_media_id(keyword: str) -> dict: +async def get_media_id(keyword: str) -> Optional[dict]: """ 获取番剧的 media_id :param keyword: 番剧名称 @@ -189,7 +191,7 @@ async def get_media_id(keyword: str) -> dict: return {} -async def get_sub_status(id_: int, sub_type: str) -> Optional[str]: +async def get_sub_status(id_: str, sub_type: str) -> Optional[str]: """ 获取订阅状态 :param id_: 订阅 id @@ -211,7 +213,7 @@ async def get_sub_status(id_: int, sub_type: str) -> Optional[str]: # return "发生了预料之外的错误..请稍后再试或联系管理员....." -async def _get_live_status(id_: int) -> Optional[str]: +async def _get_live_status(id_: str) -> Optional[str]: """ 获取直播订阅状态 :param id_: 直播间 id @@ -222,65 +224,67 @@ async def _get_live_status(id_: int) -> Optional[str]: room_id = live_info["room_id"] live_status = live_info["live_status"] cover = live_info["user_cover"] - sub = await BilibiliSub.get_or_none(sub_id=id_) - if sub.live_status != live_status: - await BilibiliSub.sub_handle(id_, live_status=live_status) - if sub.live_status in [0, 2] and live_status == 1: - return ( - f"" - f"{image(cover)}\n" - f"{sub.uname} 开播啦!\n" - f"标题:{title}\n" - f"直链:https://live.bilibili.com/{room_id}" - ) + if sub := await BilibiliSub.get_or_none(sub_id=id_): + if sub.live_status != live_status: + await BilibiliSub.sub_handle(id_, live_status=live_status) + if sub.live_status in [0, 2] and live_status == 1: + return ( + f"" + f"{image(cover)}\n" + f"{sub.uname} 开播啦!\n" + f"标题:{title}\n" + f"直链:https://live.bilibili.com/{room_id}" + ) return None -async def _get_up_status(id_: int) -> Optional[str]: +async def _get_up_status(id_: str) -> Optional[str]: """ 获取用户投稿状态 :param id_: 订阅 id :return: """ - _user = await BilibiliSub.get_or_none(sub_id=id_) - """bilibili_api.user库中User类的get_user_info改为bilireq.user库的get_user_info方法""" - user_info = await get_user_card(_user.uid) - uname = user_info["name"] - """bilibili_api.user库中User类的get_videos改为bilireq.user库的get_videos方法""" - video_info = await get_videos(_user.uid) - latest_video_created = 0 - video = None - dividing_line = "\n-------------\n" - if _user.uname != uname: - await BilibiliSub.sub_handle(id_, uname=uname) - dynamic_img, dynamic_upload_time, link = await get_user_dynamic(_user.uid, _user) - if video_info["list"].get("vlist"): - video = video_info["list"]["vlist"][0] - latest_video_created = video["created"] rst = "" - if dynamic_img: - await BilibiliSub.sub_handle(id_, dynamic_upload_time=dynamic_upload_time) - rst += f"{uname} 发布了动态!\n" f"{dynamic_img}\n{link}" - if ( - latest_video_created - and _user.latest_video_created - and video - and _user.latest_video_created < latest_video_created - ): - rst = rst + dividing_line if rst else rst - await BilibiliSub.sub_handle(id_, latest_video_created=latest_video_created) - rst += ( - f'{image(video["pic"])}\n' - f"{uname} 投稿了新视频啦\n" - f'标题:{video["title"]}\n' - f'Bvid:{video["bvid"]}\n' - f'直链:https://www.bilibili.com/video/{video["bvid"]}' + if _user := await BilibiliSub.get_or_none(sub_id=id_): + """bilibili_api.user库中User类的get_user_info改为bilireq.user库的get_user_info方法""" + user_info = await get_user_card(_user.uid) + uname = user_info["name"] + """bilibili_api.user库中User类的get_videos改为bilireq.user库的get_videos方法""" + video_info = await get_videos(_user.uid) + latest_video_created = 0 + video = None + dividing_line = "\n-------------\n" + if _user.uname != uname: + await BilibiliSub.sub_handle(id_, uname=uname) + dynamic_img, dynamic_upload_time, link = await get_user_dynamic( + _user.uid, _user ) - rst = None if rst == dividing_line else rst + if video_info["list"].get("vlist"): + video = video_info["list"]["vlist"][0] + latest_video_created = video["created"] + if dynamic_img: + await BilibiliSub.sub_handle(id_, dynamic_upload_time=dynamic_upload_time) + rst += f"{uname} 发布了动态!\n" f"{dynamic_img}\n{link}" + if ( + latest_video_created + and _user.latest_video_created + and video + and _user.latest_video_created < latest_video_created + ): + rst = rst + dividing_line if rst else rst + await BilibiliSub.sub_handle(id_, latest_video_created=latest_video_created) + rst += ( + f'{image(video["pic"])}\n' + f"{uname} 投稿了新视频啦\n" + f'标题:{video["title"]}\n' + f'Bvid:{video["bvid"]}\n' + f'直链:https://www.bilibili.com/video/{video["bvid"]}' + ) + rst = None if rst == dividing_line else rst return rst -async def _get_season_status(id_) -> Optional[str]: +async def _get_season_status(id_: str) -> Optional[str]: """ 获取 番剧 更新状态 :param id_: 番剧 id @@ -288,17 +292,18 @@ async def _get_season_status(id_) -> Optional[str]: """bilibili_api.bangumi库中get_meta改为bilireq.bangumi库的get_meta方法""" season_info = await get_meta(id_) title = season_info["media"]["title"] - _idx = (await BilibiliSub.get_or_none(sub_id=id_)).season_current_episode - new_ep = season_info["media"]["new_ep"]["index"] - if new_ep != _idx: - await BilibiliSub.sub_handle( - id_, season_current_episode=new_ep, season_update_time=datetime.now() - ) - return ( - f'{image(season_info["media"]["cover"])}\n' - f"[{title}]更新啦\n" - f"最新集数:{new_ep}" - ) + if data := await BilibiliSub.get_or_none(sub_id=id_): + _idx = data.season_current_episode + new_ep = season_info["media"]["new_ep"]["index"] + if new_ep != _idx: + await BilibiliSub.sub_handle( + id_, season_current_episode=new_ep, season_update_time=datetime.now() + ) + return ( + f'{image(season_info["media"]["cover"])}\n' + f"[{title}]更新啦\n" + f"最新集数:{new_ep}" + ) return None diff --git a/plugins/bilibili_sub/model.py b/plugins/bilibili_sub/model.py index 74e49aa7..3b73630f 100755 --- a/plugins/bilibili_sub/model.py +++ b/plugins/bilibili_sub/model.py @@ -11,13 +11,13 @@ class BilibiliSub(Model): id = fields.IntField(pk=True, generated=True, auto_increment=True) """自增id""" - sub_id = fields.IntField() + sub_id = fields.CharField(255) """订阅id""" sub_type = fields.CharField(255) """订阅类型""" sub_users = fields.TextField() """订阅用户""" - live_short_id = fields.IntField(null=True) + live_short_id = fields.CharField(255, null=True) """直播短id""" live_status = fields.IntField(null=True) """直播状态 0: 停播 1: 直播""" @@ -46,11 +46,11 @@ class BilibiliSub(Model): @classmethod async def sub_handle( cls, - sub_id: int, + sub_id: str, sub_type: Optional[str] = None, sub_user: str = "", *, - live_short_id: Optional[int] = None, + live_short_id: Optional[str] = None, live_status: Optional[int] = None, dynamic_upload_time: int = 0, uid: Optional[int] = None, @@ -183,7 +183,9 @@ class BilibiliSub(Model): return live_data, up_data, season_data @classmethod - async def _run_script(cls): + def _run_script(cls): return [ "ALTER TABLE bilibili_sub ALTER COLUMN season_update_time TYPE timestamp with time zone USING season_update_time::timestamp with time zone;", + "alter table bilibili_sub alter COLUMN sub_id type varchar(255);", # 将sub_id字段改为字符串 + "alter table bilibili_sub alter COLUMN live_short_id type varchar(255);", # 将live_short_id字段改为字符串 ] diff --git a/plugins/bilibili_sub/utils.py b/plugins/bilibili_sub/utils.py index 861b62ea..ee2094f4 100755 --- a/plugins/bilibili_sub/utils.py +++ b/plugins/bilibili_sub/utils.py @@ -1,16 +1,18 @@ -from utils.image_utils import BuildImage -from configs.path_config import IMAGE_PATH -from utils.http_utils import AsyncHttpx, get_user_agent +from io import BytesIO + # from bilibili_api import user from bilireq.user import get_user_info from httpx import AsyncClient -from io import BytesIO +from configs.path_config import IMAGE_PATH +from utils.http_utils import AsyncHttpx, get_user_agent +from utils.image_utils import BuildImage BORDER_PATH = IMAGE_PATH / "border" BORDER_PATH.mkdir(parents=True, exist_ok=True) BASE_URL = "https://api.bilibili.com" + async def get_pic(url: str) -> bytes: """ 获取图像 @@ -71,7 +73,7 @@ def _create_live_des_image( bk.paste(cover, (0, 100), center_type="by_width") -async def get_meta(media_id: int, auth=None, reqtype="both", **kwargs): +async def get_meta(media_id: str, auth=None, reqtype="both", **kwargs): """ 根据番剧 ID 获取番剧元数据信息, 作为bilibili_api和bilireq的替代品。 @@ -81,8 +83,10 @@ async def get_meta(media_id: int, auth=None, reqtype="both", **kwargs): url = f"{BASE_URL}/pgc/review/user" params = {"media_id": media_id} - raw_json = await get(url, raw=True, params=params, auth=auth, reqtype=reqtype, **kwargs) - return raw_json['result'] + raw_json = await get( + url, raw=True, params=params, auth=auth, reqtype=reqtype, **kwargs + ) + return raw_json["result"] async def get_videos( @@ -128,7 +132,10 @@ async def get_videos( ) return raw_json["data"] -async def get_user_card(mid, photo: bool = False, auth=None, reqtype="both", **kwargs): + +async def get_user_card( + mid: str, photo: bool = False, auth=None, reqtype="both", **kwargs +): from bilireq.utils import get url = f"{BASE_URL}/x/web-interface/card"