feat(ingest): parse video refs and fetch detail by bvid
This commit is contained in:
1 parent
e903c49921
commit
d2adb65e08
6 files changed
+410
No files matched your search
@@ -146,6 +146,89 @@ class ViewStat:
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class VideoDetail:
|
||||
"""``x/web-interface/view`` 的完整元数据 + 七项统计。
|
||||
|
||||
比 :class:`ViewStat` 多出 UP、时长、分 P 数、封面等字段,供手动入库建库使用。
|
||||
"""
|
||||
|
||||
aid: int
|
||||
bvid: str | None
|
||||
title: str
|
||||
up_mid: int | None
|
||||
up_name: str | None
|
||||
pubdate: int
|
||||
duration: int
|
||||
pages: int | None
|
||||
cover: str | None
|
||||
stat: ViewStat
|
||||
|
||||
def metrics(self) -> dict[str, int]:
|
||||
return self.stat.metrics()
|
||||
|
||||
@classmethod
|
||||
def from_api(cls, item: Mapping[str, Any]) -> "VideoDetail":
|
||||
stat = ViewStat.from_api(item)
|
||||
owner = item.get("owner") or {}
|
||||
if not isinstance(owner, Mapping):
|
||||
owner = {}
|
||||
raw_mid = owner.get("mid")
|
||||
up_mid = (
|
||||
raw_mid
|
||||
if isinstance(raw_mid, int) and not isinstance(raw_mid, bool)
|
||||
else None
|
||||
)
|
||||
up_name = owner.get("name")
|
||||
if not isinstance(up_name, str) or not up_name:
|
||||
up_name = None
|
||||
|
||||
raw_duration = item.get("duration")
|
||||
duration = (
|
||||
raw_duration
|
||||
if isinstance(raw_duration, int)
|
||||
and not isinstance(raw_duration, bool)
|
||||
and raw_duration >= 0
|
||||
else 0
|
||||
)
|
||||
|
||||
pages: int | None = None
|
||||
raw_pages = item.get("pages")
|
||||
if isinstance(raw_pages, list) and raw_pages:
|
||||
pages = len(raw_pages)
|
||||
else:
|
||||
raw_videos = item.get("videos")
|
||||
if (
|
||||
isinstance(raw_videos, int)
|
||||
and not isinstance(raw_videos, bool)
|
||||
and raw_videos > 0
|
||||
):
|
||||
pages = raw_videos
|
||||
|
||||
raw_pubdate = item.get("pubdate") or item.get("ctime")
|
||||
pubdate = (
|
||||
raw_pubdate
|
||||
if isinstance(raw_pubdate, int) and not isinstance(raw_pubdate, bool)
|
||||
else 0
|
||||
)
|
||||
cover = item.get("pic")
|
||||
if not isinstance(cover, str) or not cover:
|
||||
cover = None
|
||||
|
||||
return cls(
|
||||
aid=stat.aid,
|
||||
bvid=stat.bvid,
|
||||
title=stat.title,
|
||||
up_mid=up_mid,
|
||||
up_name=up_name,
|
||||
pubdate=pubdate,
|
||||
duration=duration,
|
||||
pages=pages,
|
||||
cover=cover,
|
||||
stat=stat,
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class FanStat:
|
||||
mid: int
|
||||
|
||||
Reference in new issue
Block a user