增强:添加批量注册功能和支持文件
This commit is contained in:
@@ -9,9 +9,14 @@ from aiosmtpd.handlers import Message
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
import traceback
|
||||
|
||||
from ..models.domain import Domain
|
||||
from ..models.mailbox import Mailbox
|
||||
from ..utils import email_parser
|
||||
from ..models import Email
|
||||
|
||||
from aiosmtpd.smtp import SMTP, Session, Envelope
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -34,29 +39,43 @@ class EmailHandler(Message):
|
||||
async def handle_DATA(self, server, session, envelope):
|
||||
"""处理接收到的邮件数据"""
|
||||
try:
|
||||
# 获取收件人和发件人
|
||||
peer = session.peer
|
||||
mail_from = envelope.mail_from
|
||||
rcpt_tos = envelope.rcpt_tos
|
||||
logging.info(f"收到邮件: 发件人={envelope.mail_from}, 收件人={envelope.rcpt_tos}")
|
||||
|
||||
# 获取原始邮件内容
|
||||
data = envelope.content
|
||||
mail = email.message_from_bytes(data, policy=default)
|
||||
# 保存原始邮件数据
|
||||
data = envelope.content.decode('utf-8', errors='replace')
|
||||
|
||||
# 保存邮件到存储服务
|
||||
for rcpt in rcpt_tos:
|
||||
result = await self.mail_store.save_email(mail_from, rcpt, mail, data)
|
||||
# 解析邮件数据
|
||||
message = email_parser.Parser().parsestr(data)
|
||||
subject = message.get('Subject', '')
|
||||
logging.info(f"邮件主题: {subject}")
|
||||
|
||||
# 记录邮件结构和内容
|
||||
logging.debug(f"邮件结构: is_multipart={message.is_multipart()}")
|
||||
if message.is_multipart():
|
||||
logging.debug(f"多部分邮件: 部分数量={len(list(message.walk()))}")
|
||||
for i, part in enumerate(message.walk()):
|
||||
content_type = part.get_content_type()
|
||||
logging.debug(f"部分 {i+1}: 内容类型={content_type}")
|
||||
|
||||
# 使用邮件存储服务保存邮件
|
||||
success, error_msg = await self.mail_store.save_email(
|
||||
message,
|
||||
envelope.mail_from,
|
||||
envelope.rcpt_tos,
|
||||
raw_data=data
|
||||
)
|
||||
|
||||
if success:
|
||||
logging.info(f"邮件保存成功: 来自 {envelope.mail_from} 发送给 {envelope.rcpt_tos}")
|
||||
return '250 消息接收完成'
|
||||
else:
|
||||
logging.error(f"邮件保存失败: {error_msg}")
|
||||
return '451 处理邮件时出现错误,请稍后重试'
|
||||
|
||||
# 记录日志
|
||||
if result:
|
||||
logger.info(f"邮件已保存: {mail_from} -> {rcpt}, 主题: {mail.get('Subject')}")
|
||||
else:
|
||||
logger.warning(f"邮件未保存: {mail_from} -> {rcpt}, 可能是无效地址")
|
||||
|
||||
return '250 Message accepted for delivery'
|
||||
except Exception as e:
|
||||
logger.error(f"处理邮件时出错: {str(e)}")
|
||||
return '451 Requested action aborted: error in processing'
|
||||
logging.error(f"处理邮件时出错: {str(e)}")
|
||||
traceback.print_exc()
|
||||
return '451 处理邮件时出现错误,请稍后重试'
|
||||
|
||||
|
||||
# 为Windows环境自定义SMTP控制器
|
||||
@@ -133,4 +152,69 @@ class SMTPServer:
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"停止SMTP服务器失败: {str(e)}")
|
||||
return False
|
||||
return False
|
||||
|
||||
class MailHandler:
|
||||
"""邮件处理器,用于处理接收的SMTP邮件"""
|
||||
|
||||
def __init__(self, mail_store):
|
||||
self.mail_store = mail_store
|
||||
|
||||
async def handle_EHLO(self, server, session, envelope, hostname):
|
||||
session.host_name = hostname
|
||||
return '250-AUTH PLAIN\n250-SIZE 52428800\n250 SMTPUTF8'
|
||||
|
||||
async def handle_MAIL(self, server, session, envelope, address, mail_options=None):
|
||||
if not mail_options:
|
||||
mail_options = []
|
||||
envelope.mail_from = address
|
||||
envelope.mail_options.extend(mail_options)
|
||||
return '250 OK'
|
||||
|
||||
async def handle_RCPT(self, server, session, envelope, address, rcpt_options=None):
|
||||
if not rcpt_options:
|
||||
rcpt_options = []
|
||||
envelope.rcpt_tos.append(address)
|
||||
envelope.rcpt_options.extend(rcpt_options)
|
||||
return '250 OK'
|
||||
|
||||
async def handle_DATA(self, server, session, envelope):
|
||||
"""处理接收到的邮件数据"""
|
||||
try:
|
||||
logging.info(f"收到邮件: 发件人={envelope.mail_from}, 收件人={envelope.rcpt_tos}")
|
||||
|
||||
# 保存原始邮件数据
|
||||
raw_data = envelope.content.decode('utf-8', errors='replace')
|
||||
|
||||
# 解析邮件数据
|
||||
message = email_parser.parsestr(raw_data)
|
||||
subject = message.get('Subject', '')
|
||||
logging.info(f"邮件主题: {subject}")
|
||||
|
||||
# 记录邮件结构和内容
|
||||
logging.debug(f"邮件结构: is_multipart={message.is_multipart()}")
|
||||
if message.is_multipart():
|
||||
logging.debug(f"多部分邮件: 部分数量={len(list(message.walk()))}")
|
||||
for i, part in enumerate(message.walk()):
|
||||
content_type = part.get_content_type()
|
||||
logging.debug(f"部分 {i+1}: 内容类型={content_type}")
|
||||
|
||||
# 使用邮件存储服务保存邮件
|
||||
success, error_msg = await self.mail_store.save_email(
|
||||
message,
|
||||
envelope.mail_from,
|
||||
envelope.rcpt_tos,
|
||||
raw_data=raw_data
|
||||
)
|
||||
|
||||
if success:
|
||||
logging.info(f"邮件保存成功: 来自 {envelope.mail_from} 发送给 {envelope.rcpt_tos}")
|
||||
return '250 消息接收完成'
|
||||
else:
|
||||
logging.error(f"邮件保存失败: {error_msg}")
|
||||
return '451 处理邮件时出现错误,请稍后重试'
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"处理邮件时出错: {str(e)}")
|
||||
traceback.print_exc()
|
||||
return '451 处理邮件时出现错误,请稍后重试'
|
||||
Reference in New Issue
Block a user