82 lines
3.1 KiB
Plaintext
82 lines
3.1 KiB
Plaintext
def _conversation_rows(
|
|
message_path: Path,
|
|
account: str,
|
|
users: dict[str, str],
|
|
conversations: dict[str, str],
|
|
query: str,
|
|
limit: int,
|
|
offset: int = 0,
|
|
) -> tuple[list[dict[str, Any]], int, int]:
|
|
index = _message_index(message_path)
|
|
ordered = index["ordered"]
|
|
needle = str(query or "").strip().casefold()
|
|
offset = max(0, int(offset))
|
|
candidates = ordered if needle else ordered[offset:offset + limit]
|
|
_ensure_previews(message_path, index, candidates)
|
|
result = []
|
|
matching = 0
|
|
for conversation_id in candidates:
|
|
name = _conversation_name(account, conversation_id, users, conversations)
|
|
preview = index["previews"][conversation_id]
|
|
if needle and needle not in f"{name} {conversation_id} {preview['text']}".casefold():
|
|
continue
|
|
if needle:
|
|
matching += 1
|
|
if matching <= offset:
|
|
continue
|
|
group = index["conversations"][conversation_id]
|
|
result.append({
|
|
"id": conversation_id, "name": name, "kind": _conversation_kind(conversation_id),
|
|
"messageCount": len(group["rows"]), "lastTime": _format_time(group["lastTimestamp"]),
|
|
"lastTimestamp": group["lastTimestamp"], "preview": preview["text"][:160],
|
|
"lastDirection": "发出" if preview["sender"] == account else "收到",
|
|
})
|
|
if len(result) >= limit:
|
|
break
|
|
return result, len(ordered), index["total_messages"]
|
|
|
|
|
|
def _messages(
|
|
message_path: Path,
|
|
account: str,
|
|
conversation_id: str,
|
|
users: dict[str, str],
|
|
limit: int,
|
|
offset: int = 0,
|
|
) -> list[dict[str, Any]]:
|
|
if not conversation_id:
|
|
return []
|
|
index = _message_index(message_path)
|
|
rows = (index["conversations"].get(conversation_id) or {}).get("rows", [])
|
|
offset = max(0, int(offset))
|
|
limit = max(1, min(int(limit), 1000))
|
|
end = max(0, len(rows) - offset)
|
|
row_ids = list(rows[max(0, end - limit):end])
|
|
revision = index["revision"]
|
|
key = (revision[0], conversation_id, limit, offset)
|
|
records = _cached("messages", key, revision, lambda: _read_message_rows(message_path, index, row_ids))
|
|
result = []
|
|
for row_id in row_ids:
|
|
item = records.get(row_id)
|
|
if item is None:
|
|
continue
|
|
sender_id = str(item.get("sender_id") or "")
|
|
try:
|
|
timestamp = float(item.get("send_time") or 0)
|
|
if not math.isfinite(timestamp):
|
|
timestamp = 0.0
|
|
except (ValueError, TypeError, OverflowError):
|
|
timestamp = 0.0
|
|
result.append({
|
|
"id": str(item.get("server_id") or item.get("client_id") or ""),
|
|
"senderId": sender_id,
|
|
"sender": users.get(sender_id) or ("当前账号" if sender_id == account else sender_id),
|
|
"direction": "outbound" if sender_id == account else "inbound",
|
|
"time": _format_time(timestamp), "timestamp": timestamp,
|
|
"type": get_msg_type_name(item.get("content_type")),
|
|
"content": _content_label(item.get("content"), item.get("content_type")),
|
|
})
|
|
return result
|
|
|
|
|