diff --git a/admin/dashboard/blueprints/contacts.py b/admin/dashboard/blueprints/contacts.py index faf9898..093d536 100644 --- a/admin/dashboard/blueprints/contacts.py +++ b/admin/dashboard/blueprints/contacts.py @@ -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