add Bangumi
This commit is contained in:
93
app/modules/bangumi/__init__.py
Normal file
93
app/modules/bangumi/__init__.py
Normal file
@ -0,0 +1,93 @@
|
||||
from typing import List, Optional, Tuple, Union
|
||||
|
||||
from app.core.context import MediaInfo
|
||||
from app.log import logger
|
||||
from app.modules import _ModuleBase
|
||||
from app.modules.bangumi.bangumi import BangumiApi
|
||||
from app.utils.http import RequestUtils
|
||||
|
||||
|
||||
class BangumiModule(_ModuleBase):
|
||||
bangumiapi: BangumiApi = None
|
||||
|
||||
def init_module(self) -> None:
|
||||
self.bangumiapi = BangumiApi()
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
def test(self) -> Tuple[bool, str]:
|
||||
"""
|
||||
测试模块连接性
|
||||
"""
|
||||
ret = RequestUtils().get_res("https://api.bgm.tv/")
|
||||
if ret and ret.status_code == 200:
|
||||
return True, ""
|
||||
elif ret:
|
||||
return False, f"无法连接Bangumi,错误码:{ret.status_code}"
|
||||
return False, "Bangumi网络连接失败"
|
||||
|
||||
def init_setting(self) -> Tuple[str, Union[str, bool]]:
|
||||
pass
|
||||
|
||||
def recognize_media(self, bangumiid: int = None,
|
||||
**kwargs) -> Optional[MediaInfo]:
|
||||
"""
|
||||
识别媒体信息
|
||||
:param bangumiid: 识别的Bangumi ID
|
||||
:return: 识别的媒体信息,包括剧集信息
|
||||
"""
|
||||
if not bangumiid:
|
||||
return None
|
||||
|
||||
# 直接查询详情
|
||||
info = self.bangumi_info(bangumiid=bangumiid)
|
||||
if info:
|
||||
# 赋值TMDB信息并返回
|
||||
mediainfo = MediaInfo(bangumi_info=info)
|
||||
logger.info(f"{bangumiid} Bangumi识别结果:{mediainfo.type.value} "
|
||||
f"{mediainfo.title_year}")
|
||||
return mediainfo
|
||||
else:
|
||||
logger.info(f"{bangumiid} 未匹配到Bangumi媒体信息")
|
||||
|
||||
return None
|
||||
|
||||
def bangumi_info(self, bangumiid: int) -> Optional[dict]:
|
||||
"""
|
||||
获取Bangumi信息
|
||||
:param bangumiid: BangumiID
|
||||
:return: Bangumi信息
|
||||
"""
|
||||
if not bangumiid:
|
||||
return None
|
||||
logger.info(f"开始获取Bangumi信息:{bangumiid} ...")
|
||||
return self.bangumiapi.detail(bangumiid)
|
||||
|
||||
def bangumi_calendar(self, page: int = 1, count: int = 30) -> Optional[List[dict]]:
|
||||
"""
|
||||
获取Bangumi每日放送
|
||||
:param page: 页码
|
||||
:param count: 每页数量
|
||||
"""
|
||||
return self.bangumiapi.calendar(page, count)
|
||||
|
||||
def bangumi_credits(self, bangumiid: int, page: int = 1, count: int = 20) -> List[dict]:
|
||||
"""
|
||||
根据TMDBID查询电影演职员表
|
||||
:param bangumiid: BangumiID
|
||||
:param page: 页码
|
||||
:param count: 数量
|
||||
"""
|
||||
persons = self.bangumiapi.persons(bangumiid) or []
|
||||
if persons:
|
||||
return persons[(page - 1) * count: page * count]
|
||||
else:
|
||||
return []
|
||||
|
||||
def bangumi_recommend(self, bangumiid: int) -> List[dict]:
|
||||
"""
|
||||
根据BangumiID查询推荐电影
|
||||
:param bangumiid: BangumiID
|
||||
"""
|
||||
return self.bangumiapi.subjects(bangumiid) or []
|
154
app/modules/bangumi/bangumi.py
Normal file
154
app/modules/bangumi/bangumi.py
Normal file
@ -0,0 +1,154 @@
|
||||
from datetime import datetime
|
||||
from functools import lru_cache
|
||||
|
||||
import requests
|
||||
|
||||
from app.utils.http import RequestUtils
|
||||
|
||||
|
||||
class BangumiApi(object):
|
||||
"""
|
||||
https://bangumi.github.io/api/
|
||||
"""
|
||||
|
||||
_urls = {
|
||||
"calendar": "calendar",
|
||||
"detail": "v0/subjects/%s",
|
||||
"persons": "v0/subjects/%s/persons",
|
||||
"subjects": "v0/subjects/%s/subjects"
|
||||
}
|
||||
_base_url = "https://api.bgm.tv/"
|
||||
_req = RequestUtils(session=requests.Session())
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
@lru_cache(maxsize=128)
|
||||
def __invoke(cls, url, **kwargs):
|
||||
req_url = cls._base_url + url
|
||||
params = {}
|
||||
if kwargs:
|
||||
params.update(kwargs)
|
||||
resp = cls._req.get_res(url=req_url, params=params)
|
||||
try:
|
||||
return resp.json() if resp else None
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
def calendar(self, page: int = 1, count: int = 30):
|
||||
"""
|
||||
获取每日放送,返回items
|
||||
"""
|
||||
"""
|
||||
[
|
||||
{
|
||||
"weekday": {
|
||||
"en": "Mon",
|
||||
"cn": "星期一",
|
||||
"ja": "月耀日",
|
||||
"id": 1
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"id": 350235,
|
||||
"url": "http://bgm.tv/subject/350235",
|
||||
"type": 2,
|
||||
"name": "月が導く異世界道中 第二幕",
|
||||
"name_cn": "月光下的异世界之旅 第二幕",
|
||||
"summary": "",
|
||||
"air_date": "2024-01-08",
|
||||
"air_weekday": 1,
|
||||
"rating": {
|
||||
"total": 257,
|
||||
"count": {
|
||||
"1": 1,
|
||||
"2": 1,
|
||||
"3": 4,
|
||||
"4": 15,
|
||||
"5": 51,
|
||||
"6": 111,
|
||||
"7": 49,
|
||||
"8": 13,
|
||||
"9": 5,
|
||||
"10": 7
|
||||
},
|
||||
"score": 6.1
|
||||
},
|
||||
"rank": 6125,
|
||||
"images": {
|
||||
"large": "http://lain.bgm.tv/pic/cover/l/3c/a5/350235_A0USf.jpg",
|
||||
"common": "http://lain.bgm.tv/pic/cover/c/3c/a5/350235_A0USf.jpg",
|
||||
"medium": "http://lain.bgm.tv/pic/cover/m/3c/a5/350235_A0USf.jpg",
|
||||
"small": "http://lain.bgm.tv/pic/cover/s/3c/a5/350235_A0USf.jpg",
|
||||
"grid": "http://lain.bgm.tv/pic/cover/g/3c/a5/350235_A0USf.jpg"
|
||||
},
|
||||
"collection": {
|
||||
"doing": 920
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 358561,
|
||||
"url": "http://bgm.tv/subject/358561",
|
||||
"type": 2,
|
||||
"name": "大宇宙时代",
|
||||
"name_cn": "大宇宙时代",
|
||||
"summary": "",
|
||||
"air_date": "2024-01-22",
|
||||
"air_weekday": 1,
|
||||
"rating": {
|
||||
"total": 2,
|
||||
"count": {
|
||||
"1": 0,
|
||||
"2": 0,
|
||||
"3": 0,
|
||||
"4": 0,
|
||||
"5": 1,
|
||||
"6": 1,
|
||||
"7": 0,
|
||||
"8": 0,
|
||||
"9": 0,
|
||||
"10": 0
|
||||
},
|
||||
"score": 5.5
|
||||
},
|
||||
"images": {
|
||||
"large": "http://lain.bgm.tv/pic/cover/l/71/66/358561_UzsLu.jpg",
|
||||
"common": "http://lain.bgm.tv/pic/cover/c/71/66/358561_UzsLu.jpg",
|
||||
"medium": "http://lain.bgm.tv/pic/cover/m/71/66/358561_UzsLu.jpg",
|
||||
"small": "http://lain.bgm.tv/pic/cover/s/71/66/358561_UzsLu.jpg",
|
||||
"grid": "http://lain.bgm.tv/pic/cover/g/71/66/358561_UzsLu.jpg"
|
||||
},
|
||||
"collection": {
|
||||
"doing": 9
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"""
|
||||
ret_list = []
|
||||
result = self.__invoke(self._urls["calendar"], _ts=datetime.strftime(datetime.now(), '%Y%m%d'))
|
||||
if result:
|
||||
for item in result:
|
||||
ret_list.extend(item.get("items") or [])
|
||||
return ret_list[(page - 1) * count: page * count]
|
||||
|
||||
def detail(self, bid: int):
|
||||
"""
|
||||
获取番剧详情
|
||||
"""
|
||||
return self.__invoke(self._urls["detail"] % bid, _ts=datetime.strftime(datetime.now(), '%Y%m%d'))
|
||||
|
||||
def persons(self, bid: int):
|
||||
"""
|
||||
获取番剧人物
|
||||
"""
|
||||
return self.__invoke(self._urls["persons"] % bid, _ts=datetime.strftime(datetime.now(), '%Y%m%d'))
|
||||
|
||||
def subjects(self, bid: int):
|
||||
"""
|
||||
获取关联条目信息
|
||||
"""
|
||||
return self.__invoke(self._urls["subjects"] % bid, _ts=datetime.strftime(datetime.now(), '%Y%m%d'))
|
Reference in New Issue
Block a user