feat: improve friend circle like state handling

This commit is contained in:
liuwei
2026-04-07 13:08:12 +08:00
parent dd8c5b1829
commit 4423f64272
2 changed files with 82 additions and 9 deletions

View File

@@ -2,7 +2,8 @@ import asyncio
import xml.etree.ElementTree as ET
from datetime import datetime
from flask import Blueprint, current_app, jsonify, render_template, request
import requests
from flask import Blueprint, Response, current_app, jsonify, render_template, request, stream_with_context
from loguru import logger
from .auth import login_required
@@ -15,6 +16,41 @@ def _run_client_coro(server, coro, timeout=90):
return future.result(timeout=timeout)
def _proxy_remote_media(target_url: str) -> Response:
if not target_url:
return Response("missing url", status=400)
headers = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/123.0.0.0 Safari/537.36"
),
"Referer": "http://weixin.qq.com/"
}
range_header = request.headers.get("Range")
if range_header:
headers["Range"] = range_header
upstream = requests.get(target_url, headers=headers, stream=True, timeout=30)
response_headers = {}
for key in ("Content-Type", "Content-Length", "Content-Range", "Accept-Ranges", "Cache-Control", "ETag", "Last-Modified"):
value = upstream.headers.get(key)
if value:
response_headers[key] = value
if "Accept-Ranges" not in response_headers:
response_headers["Accept-Ranges"] = "bytes"
return Response(
stream_with_context(upstream.iter_content(chunk_size=64 * 1024)),
status=upstream.status_code,
headers=response_headers,
direct_passthrough=True
)
def _safe_text(value, default=""):
if value is None:
return default
@@ -158,14 +194,17 @@ def _normalize_like(like):
return {
"author_wxid": (
_safe_text(like.get("UserName"))
or _safe_text(like.get("Username"))
or _safe_text(like.get("username"))
or _safe_text(like.get("Wxid"))
),
"author_name": (
_safe_text(like.get("NickName"))
or _safe_text(like.get("Nickname"))
or _safe_text(like.get("nickname"))
or _safe_text(like.get("DisplayName"))
)
),
"create_time": _safe_text(like.get("CreateTime")) or _safe_text(like.get("createTime"))
}
@@ -238,6 +277,8 @@ def _normalize_post(node, server):
comment_nodes.extend(_extract_list(node.get(key)))
for key in ("LikeList", "Likes", "likeList", "likes"):
like_nodes.extend(_extract_list(node.get(key)))
for key in ("LikeUserList", "likeUserList"):
like_nodes.extend(_extract_list(node.get(key)))
return {
"id": object_id,
@@ -246,6 +287,9 @@ def _normalize_post(node, server):
"author_avatar": server.contact_manager.get_head_image(author_wxid),
"content": content,
"timestamp": timestamp,
"like_flag": _safe_text(node.get("LikeFlag")),
"is_liked": _safe_text(node.get("LikeFlag")) in ("1", "true", "True"),
"like_count": _safe_text(node.get("LikeCount")),
"location": xml_data.get("location", {}),
"media": [item for item in media if item.get("url") or item.get("thumb")],
"comments": [item for item in (_normalize_comment(x) for x in comment_nodes) if item.get("content") or item.get("author_wxid")],
@@ -445,3 +489,14 @@ def friend_circle_comment():
except Exception as exc:
logger.error(f"朋友圈评论失败: {exc}")
return jsonify({"success": False, "message": str(exc)}), 500
@friend_circle_bp.route("/api/friend_circle/media_proxy")
@login_required
def friend_circle_media_proxy():
target_url = request.args.get("url", "").strip()
try:
return _proxy_remote_media(target_url)
except Exception as exc:
logger.error(f"朋友圈媒体代理失败: {exc}")
return Response(f"proxy failed: {exc}", status=502)