feat: persist history and work caches

This commit is contained in:
2026-09-07 16:40:32 +08:00
parent 07524a36cd
commit b42b2d33da
10 changed files with 761 additions and 201 deletions
+17 -9
View File
@@ -232,8 +232,9 @@ class Session:
raise SessionError("通知详情返回了未请求的 ID,已停止处理")
return notices
async def history_notices(self):
async def history_notices(self, stop_ids=None):
notices = {}
stop_ids = set(stop_ids or ())
min_time = max_time = 0
seen_cursors = set()
for _ in range(1000):
@@ -256,13 +257,14 @@ class Session:
not isinstance(row, dict) for row in rows
):
raise SessionError("历史通知列表格式无效")
reached_cache = False
for row in rows:
if str(row.get("user_id")) != self.uid:
raise SessionError("历史通知所属身份不符")
nid = row.get("nid_str") or row.get("nid")
validate_uid(nid)
nid = validate_uid(row.get("nid_str") or row.get("nid"))
reached_cache = reached_cache or nid in stop_ids
notices.setdefault(nid, row)
if not payload.get("has_more"):
if reached_cache or not payload.get("has_more"):
return list(notices.values())
cursor = (payload.get("min_time"), payload.get("max_time"))
if cursor in seen_cursors or cursor == (min_time, max_time):
@@ -273,15 +275,16 @@ class Session:
min_time, max_time = cursor
raise SessionError("历史通知超过 50000 条,已停止以避免无限分页")
async def works(self, all_pages=False):
async def works(self, all_pages=False, stop_ids=None):
profile = await self.identity()
stop_ids = set(stop_ids or ())
sec_uid = profile.get("sec_uid") or profile.get("secUid")
if not isinstance(sec_uid, str) or not sec_uid:
raise SessionError("当前账号缺少作品列表身份参数")
works = {}
cursor = 0
seen_cursors = set()
pages = 1000 if all_pages else 1
pages = 1000 if all_pages or stop_ids else 1
for _ in range(pages):
response = await self.json(
works_request_script(sec_uid, cursor), main_world=True
@@ -302,12 +305,13 @@ class Session:
not isinstance(row, dict) for row in rows
):
raise SessionError("作品列表格式无效")
reached_cache = False
for row in rows:
author = row.get("author") or {}
if str(author.get("uid")) != self.uid:
raise SessionError("作品列表所属身份不符")
ident = row.get("aweme_id") or row.get("awemeId")
validate_uid(ident)
ident = validate_uid(row.get("aweme_id") or row.get("awemeId"))
reached_cache = reached_cache or ident in stop_ids
cover = ((row.get("video") or {}).get("cover") or {}).get(
"url_list"
) or []
@@ -324,7 +328,11 @@ class Session:
"business": row,
},
)
if not all_pages or not payload.get("has_more"):
if (
reached_cache
or (not all_pages and not stop_ids)
or not payload.get("has_more")
):
return list(works.values())
next_cursor = payload.get("max_cursor")
if type(next_cursor) not in (int, float) or next_cursor < 0: