feat(p1): add daily snapshots and fan tracking
Implement P1: seven-metric view snapshots, relation/stat fan snapshots, failure placeholders, resume by daily completion markers, Cookie login warnings, daily SQLite backups, Shanghai daily scheduling, and CLI snapshot/auth-check commands. Real read-only run captured 795/795 videos successfully over 1124s with a verified daily backup.
This commit is contained in:
1 parent
ee289bfa56
commit
5c2ab7b187
20 files changed
+1680
-54
No files matched your search
@@ -25,8 +25,13 @@ from fixtures import ( # noqa: E402
|
||||
FOLDERS_PAYLOAD,
|
||||
IDS_PAYLOAD,
|
||||
INVALID_INFO,
|
||||
NAV_PAYLOAD,
|
||||
RELATION_PAYLOAD,
|
||||
VALID_INFO,
|
||||
VIEW_PAYLOAD,
|
||||
VIEW_UNAVAILABLE,
|
||||
info_for,
|
||||
view_for,
|
||||
)
|
||||
|
||||
|
||||
@@ -274,6 +279,88 @@ def test_timeout_and_method_forwarded():
|
||||
assert call["timeout"] == 30
|
||||
|
||||
|
||||
def test_view_seven_metrics():
|
||||
transport = QueueTransport([http_json(VIEW_PAYLOAD)])
|
||||
client, _ = make_client(transport)
|
||||
stat = client.view(117530286889638)
|
||||
assert stat.aid == 117530286889638
|
||||
assert stat.bvid == "BV1xvxi6LEZD"
|
||||
assert stat.metrics() == {
|
||||
"view": 819, "like": 44, "favorite": 43, "coin": 9,
|
||||
"share": 1, "reply": 16, "danmaku": 7,
|
||||
}
|
||||
assert "aid=117530286889638" in transport.calls[0]["url"]
|
||||
|
||||
|
||||
def test_view_unavailable_and_malformed():
|
||||
transport = QueueTransport([
|
||||
http_json(VIEW_UNAVAILABLE), http_json(VIEW_UNAVAILABLE),
|
||||
])
|
||||
client, _ = make_client(transport)
|
||||
try:
|
||||
client.view(1)
|
||||
except BilibiliAPIError as exc:
|
||||
assert exc.code == 62012
|
||||
else:
|
||||
raise AssertionError("不可访问视频应抛业务错误")
|
||||
|
||||
payload = view_for(1)
|
||||
payload["data"]["stat"].pop("coin")
|
||||
bad = http_json(payload)
|
||||
transport = QueueTransport([bad, bad])
|
||||
client, _ = make_client(transport)
|
||||
try:
|
||||
client.view(1)
|
||||
except BilibiliProtocolError as exc:
|
||||
assert "coin" in str(exc)
|
||||
else:
|
||||
raise AssertionError("缺少 stat 字段应报协议错误")
|
||||
|
||||
|
||||
def test_relation_stat():
|
||||
transport = QueueTransport([http_json(RELATION_PAYLOAD)])
|
||||
client, _ = make_client(transport)
|
||||
fan = client.relation_stat(37754047)
|
||||
assert fan.mid == 37754047
|
||||
assert fan.follower == 2767268
|
||||
assert fan.following == 95
|
||||
assert "vmid=37754047" in transport.calls[0]["url"]
|
||||
|
||||
|
||||
def test_check_login():
|
||||
transport = QueueTransport([http_json(NAV_PAYLOAD)])
|
||||
client, _ = make_client(transport)
|
||||
state = client.check_login()
|
||||
assert state.is_login is True
|
||||
assert state.mid == 28802351
|
||||
assert state.uname == "冷萃编译器"
|
||||
assert "SESSDATA=secret" in transport.calls[0]["headers"]["cookie"]
|
||||
|
||||
transport = QueueTransport([http_json({
|
||||
"code": 0, "message": "0", "ttl": 1,
|
||||
"data": {"isLogin": False, "mid": 0, "uname": ""},
|
||||
})])
|
||||
client, _ = make_client(transport)
|
||||
state = client.check_login()
|
||||
assert state.is_login is False and state.mid == 0
|
||||
|
||||
transport = QueueTransport([http_json({"code": -101, "message": "账号未登录", "data": None})])
|
||||
client, _ = make_client(transport)
|
||||
state = client.check_login()
|
||||
assert state.is_login is False
|
||||
assert state.code == -101
|
||||
assert "账号未登录" in state.message
|
||||
|
||||
|
||||
def test_check_login_without_cookie_makes_no_request():
|
||||
transport = QueueTransport([])
|
||||
client, _ = make_client(transport, cookie="")
|
||||
state = client.check_login()
|
||||
assert state.is_login is False
|
||||
assert state.message == "未配置 cookie"
|
||||
assert transport.calls == []
|
||||
|
||||
|
||||
def main():
|
||||
test_fav_ids_parse_and_anonymous_header()
|
||||
test_anonymous_failure_falls_back_to_full_cookie()
|
||||
@@ -288,6 +375,11 @@ def main():
|
||||
test_fav_infos_chunk_size_validation()
|
||||
test_pacer_delays_after_first_request()
|
||||
test_timeout_and_method_forwarded()
|
||||
test_view_seven_metrics()
|
||||
test_view_unavailable_and_malformed()
|
||||
test_relation_stat()
|
||||
test_check_login()
|
||||
test_check_login_without_cookie_makes_no_request()
|
||||
print("OK: B 站只读客户端契约与重试测试全部通过")
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user