feat: EOD 23:15 seal + midnight seed shell for video/fans

Move daily snapshot/fans to 23:15 and add 00:01 seed that clones
last_completed ok=1 rows into today without advancing completed.
Evening runs force through seed markers; growth previous is per-aid
adjacent. Home shows short-update clock + 全站数据 date, and 收录视频
counts.
This commit is contained in:
bot-ci committed 2026-11-02 12:38:55 +08:00
1 parent 374b138041
commit 8a9cb21408
17 files changed
+520 -39

No files matched your search

+96 -1
View File
@@ -501,7 +501,7 @@ def test_run_recent_videos_refreshes_without_completion_markers():
def test_full_snapshot_skips_ok_rows_including_hourly_refresh():
"""00:01 全量:同日 ok=1(含小时任务刚刷)直接跳过。"""
"""晚间全量(未 force):同日 ok=1(含小时任务刚刷)直接跳过。"""
clock = 1_800_000_000
with tempfile.TemporaryDirectory() as tmp:
transport = SnapshotTransport({1: view_for(1), 2: view_for(2)})
@@ -530,6 +530,99 @@ def test_full_snapshot_skips_ok_rows_including_hourly_refresh():
def test_seed_from_last_completed_does_not_mark_completed():
clock = 1_800_000_000
with tempfile.TemporaryDirectory() as tmp:
transport = SnapshotTransport({1: view_for(1)})
db, repo, service = make_service(tmp, transport, track_fans=(37754047,))
try:
add_video(repo, 1)
yday = "2026-10-30"
today = "2026-10-31"
repo.upsert_snapshot(
yday, 1,
metrics={"view": 10, "like": 1, "coin": 0, "favorite": 0,
"share": 0, "reply": 0, "danmaku": 0},
ok=True, err=None, captured_at=clock - 86400,
)
repo.upsert_up_stat(
yday, 37754047, follower=100, following=1, ok=True,
captured_at=clock - 86400,
)
repo.kv_set("snapshot:last_completed", yday)
repo.kv_set(service.completed_key(yday), "1")
summary = service.run_seed_from_last_completed(date=today)
assert summary.success == 1
assert summary.fans_ok == 1
assert repo.kv_get(service.seeded_key(today)) == "1"
assert repo.kv_get(service.fans_seeded_key(today)) == "1"
assert repo.kv_get(service.completed_key(today)) is None
assert repo.kv_get("snapshot:last_completed") == yday
row = repo.get_snapshot(today, 1)
assert row is not None
assert int(row["view"]) == 10
assert row["src"] == "seed"
fan = repo.get_up_stat(today, 37754047)
assert fan is not None and int(fan["follower"]) == 100
# 幂等:再 seed 不重复
again = service.run_seed_from_last_completed(date=today)
assert again.already_completed is True
assert transport.count("/web-interface/view") == 0
finally:
db.close()
def test_seeded_day_skips_without_force_and_seals_with_force():
clock = 1_800_000_000
with tempfile.TemporaryDirectory() as tmp:
fan_payload = dict(RELATION_PAYLOAD)
fan_payload["data"] = dict(RELATION_PAYLOAD["data"])
fan_payload["data"]["follower"] = 999
transport = SnapshotTransport({1: view_for(1, view=555)}, fan=fan_payload)
db, repo, service = make_service(tmp, transport, track_fans=(37754047,))
try:
add_video(repo, 1)
yday = "2026-10-30"
today = DATE
repo.upsert_snapshot(
yday, 1,
metrics={"view": 10, "like": 1, "coin": 0, "favorite": 0,
"share": 0, "reply": 0, "danmaku": 0},
ok=True, err=None, captured_at=clock - 86400,
)
repo.upsert_up_stat(
yday, 37754047, follower=100, following=1, ok=True,
captured_at=clock - 86400,
)
repo.kv_set("snapshot:last_completed", yday)
service.run_seed_from_last_completed(date=today)
pending = service.run_if_needed(date=today)
assert pending.completed is False
assert pending.already_completed is False
assert repo.kv_get(service.seeded_key(today)) == "1"
assert transport.count("/web-interface/view") == 0
sealed = service.run_if_needed(date=today, force=True)
assert sealed.completed is True
assert sealed.success >= 1
assert repo.kv_get(service.completed_key(today)) == "1"
assert repo.kv_get("snapshot:last_completed") == today
assert repo.kv_get(service.seeded_key(today)) is None
row = repo.get_snapshot(today, 1)
assert int(row["view"]) == 555 # 被真实 view 覆盖
assert row["src"] == "view"
fans = service.run_fans_if_needed(date=today, force=True)
assert fans.fans_ok >= 1
assert repo.kv_get(service.fans_seeded_key(today)) is None
assert int(repo.get_up_stat(today, 37754047)["follower"]) == 999
finally:
db.close()
def main():
test_snapshot_success_resume_and_force()
test_resume_skips_ok_and_retries_failed()
@@ -545,6 +638,8 @@ def main():
test_backup_failure_retries_without_api()
test_run_recent_videos_refreshes_without_completion_markers()
test_full_snapshot_skips_ok_rows_including_hourly_refresh()
test_seed_from_last_completed_does_not_mark_completed()
test_seeded_day_skips_without_force_and_seals_with_force()
print("OK: 每日快照、断点续跑、失败占位与粉丝采集测试全部通过")