改动结果:
聊天窗口工具栏新增了“表情”按钮,打开表情库弹窗。 表情库会从历史“已下载落盘的表情消息”里自动聚合。 选中后直接通过 send_emoji_message(wxid, md5, total_length) 发原生表情,不是当普通图片发。 仍保持你现在的发送通道和聊天刷新逻辑。 主要改动文件: 后端接口与发送支持:contacts.py 表情资源查询:message_storage.py 前端表情面板与发送交互:contacts_management.html 新增接口: GET /contacts/api/emojis:返回聚合后的表情库(md5、total_length、预览图)。 POST /contacts/api/send_message 新增 type=emoji。 我也做了 Python 语法检查,相关后端文件都通过了。 你可以直接在聊天弹窗里点“表情”试一下。如果表情库为空,通常是该群还没落盘到 image_path,让媒体下载功能先抓几条表情就会出现。
This commit is contained in:
@@ -17,7 +17,6 @@ message_thread_pool = ThreadPoolExecutor(max_workers=10, thread_name_prefix="mes
|
||||
# 创建共享的事件循环
|
||||
shared_loop = None
|
||||
loop_lock = threading.Lock()
|
||||
_PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
|
||||
_EMOJI_MD5_RE = re.compile(r'md5\s*=\s*[\"\']([0-9a-fA-F]{16,64})[\"\']', re.IGNORECASE)
|
||||
_EMOJI_TOTALLEN_RE = re.compile(r'(?:totallen|total_len|len)\s*=\s*[\"\'](\d+)[\"\']', re.IGNORECASE)
|
||||
|
||||
@@ -149,16 +148,33 @@ def _extract_emoji_meta(attachment_url: str, image_path: str):
|
||||
md5 = ""
|
||||
total_length = 0
|
||||
|
||||
md5_match = _EMOJI_MD5_RE.search(text)
|
||||
if md5_match:
|
||||
md5 = md5_match.group(1).lower()
|
||||
|
||||
len_match = _EMOJI_TOTALLEN_RE.search(text)
|
||||
if len_match:
|
||||
# 优先按 XML 结构解析,避免纯正则误命中其他字段。
|
||||
if text.startswith("<"):
|
||||
try:
|
||||
total_length = int(len_match.group(1))
|
||||
root = ET.fromstring(text)
|
||||
emoji_node = root.find(".//emoji")
|
||||
if emoji_node is not None:
|
||||
md5 = _safe_text(emoji_node.attrib.get("md5", "")).strip().lower()
|
||||
for key in ("totallen", "total_len", "totalLen", "len"):
|
||||
value = _safe_text(emoji_node.attrib.get(key, "")).strip()
|
||||
if value.isdigit():
|
||||
total_length = int(value)
|
||||
break
|
||||
except Exception:
|
||||
total_length = 0
|
||||
pass
|
||||
|
||||
if not md5:
|
||||
md5_match = _EMOJI_MD5_RE.search(text)
|
||||
if md5_match:
|
||||
md5 = md5_match.group(1).lower()
|
||||
|
||||
if total_length <= 0:
|
||||
len_match = _EMOJI_TOTALLEN_RE.search(text)
|
||||
if len_match:
|
||||
try:
|
||||
total_length = int(len_match.group(1))
|
||||
except Exception:
|
||||
total_length = 0
|
||||
|
||||
if not md5 and image_path:
|
||||
filename = os.path.basename(_safe_text(image_path))
|
||||
@@ -166,14 +182,6 @@ def _extract_emoji_meta(attachment_url: str, image_path: str):
|
||||
if re.fullmatch(r"[0-9a-fA-F]{16,64}", stem):
|
||||
md5 = stem.lower()
|
||||
|
||||
if total_length <= 0 and image_path and image_path.startswith("/static/"):
|
||||
abs_path = os.path.join(_PROJECT_ROOT, image_path.lstrip("/").replace("/", os.sep))
|
||||
if os.path.isfile(abs_path):
|
||||
try:
|
||||
total_length = int(os.path.getsize(abs_path))
|
||||
except Exception:
|
||||
total_length = 0
|
||||
|
||||
return md5, total_length
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user