diff --git a/email_ui.py b/email_ui.py index 9e8c491..6dac013 100644 --- a/email_ui.py +++ b/email_ui.py @@ -1,15 +1,15 @@ # -*- coding: utf-8 -*- """ -email_ui.py — 一键群发工具 (强化校验版) --------------------------------------- +email_ui.py — 一键群发工具 (强化校验版,支持自定义默认称呼) +------------------------------------------------------------ 运行: python email_ui.py """ -import os, logging, re, random +import os, logging, re from datetime import datetime import gradio as gr from send_email_module import send_email -EMAIL_CONFIG_KEY = "default" # 对应 config/default.json +EMAIL_CONFIG_KEY = "default" LOG_FILE = "email_send_log.txt" logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s") @@ -17,7 +17,7 @@ logging.basicConfig(level=logging.INFO, EMAIL_RE = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$") # 简易邮箱正则 -# -------------------- 工具 -------------------- +# ---------- 工具 ---------- def _load_template(file_obj): if file_obj is None: return "" @@ -25,36 +25,31 @@ def _load_template(file_obj): return f.read() -def _error(msg): - """生成统一的红字提示 + 让 state 为空 -> Send 仍锁定""" +def _error(msg): # 统一红字提示 return gr.update(value=f"
❌ {msg}
"), None -# -------------------- 预览 -------------------- +# ---------- 预览 ---------- def preview_email(to_addrs, subject, html_file, language, - want_receipt, want_read_receipt): - # 0. 模板存在 + want_receipt, want_read_receipt, default_name): # ✨ new tpl = _load_template(html_file) if not tpl: return _error("请先上传 HTML 模板") - # 1. 收件人非空且格式合法 raw_addrs = [a.strip() for a in to_addrs.split(",") if a.strip()] if not raw_addrs: return _error("收件人邮箱不能为空") if invalid := [a for a in raw_addrs if not EMAIL_RE.match(a)]: return _error(f"邮箱格式非法: {', '.join(invalid)}") - # 2. 主题非空 if not subject.strip(): return _error("主题不能为空") - # 3. 模板至少包含 {{recipient_name}} if "{{recipient_name}}" not in tpl: return _error("模板缺少 {{recipient_name}} 占位符") - # ---- 全部通过,生成预览 ---- - preview = (tpl.replace("{{recipient_name}}", "there") + # 生成预览,用用户填写的 default_name(留空时仍展示 there) + preview = (tpl.replace("{{recipient_name}}", default_name or "there") .replace("{{recipient_email}}", "example@example.com") .replace("{{encoded_recipient_email}}", "ENCODED_EXAMPLE") .replace("{{timestamp}}", datetime.now().isoformat())) @@ -66,18 +61,24 @@ def preview_email(to_addrs, subject, html_file, language, "language": language, "want_receipt": want_receipt, "want_read_receipt": want_read_receipt, + "default_name": default_name.strip(), # ✨ new } return gr.update(value=preview), state -# -------------------- 发送 -------------------- +# ---------- 发送 ---------- def send_emails(state): if not state: return "⚠️ 请先 Preview 成功后再发送。" + out_lines = [] for addr in state["addresses"]: res = send_email( - EMAIL_CONFIG_KEY, addr, state["subject"], state["template"], "", + EMAIL_CONFIG_KEY, + addr, + state["subject"], + state["template"], + state["default_name"], # ✨ new (可为空串) request_receipt=state["want_receipt"], request_read_receipt=state["want_read_receipt"], language=state["language"], @@ -90,7 +91,7 @@ def send_emails(state): return "