Files
emailsystemv2/old/app/services/mail_store.py
huangzhenpc a8d1b41381 first commit
2025-02-26 18:29:10 +08:00

140 lines
4.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import logging
import os
import email
from email.policy import default
from sqlalchemy.orm import Session
from datetime import datetime
import re
import redis
from ..models.domain import Domain
from ..models.mailbox import Mailbox
from ..models.email import Email
from ..models.attachment import Attachment
logging.basicConfig(
level=logging.DEBUG, # 设置日志级别为DEBUG
format='%(asctime)s - %(levelname)s - %(message)s', # 日志格式
filename='app.log', # 日志文件名
filemode='a' # 追加模式
)
logger = logging.getLogger(__name__)
# 连接到 Redis
redis_client = redis.StrictRedis(host='localhost', port=6379, db=0)
class MailStore:
"""邮件存储服务,负责保存和检索邮件"""
def __init__(self, db_session_factory, storage_path=None):
"""
初始化邮件存储服务
参数:
db_session_factory: 数据库会话工厂函数
storage_path: 附件存储路径
"""
self.db_session_factory = db_session_factory
self.storage_path = storage_path or os.path.join(os.getcwd(), 'email_data')
# 确保存储目录存在
if not os.path.exists(self.storage_path):
os.makedirs(self.storage_path)
async def save_email(self, message, sender, recipients, raw_data=None):
logging.info(f"开始保存邮件: 发件人={sender}, 收件人={recipients}")
# 处理收件人列表
if recipients is None:
logging.error("收件人列表为None无法保存邮件")
return False, "收件人列表为None"
elif isinstance(recipients, list):
recipients_list = recipients # 如果是列表,直接使用
else:
recipients_list = recipients.split(",") # 假设是以逗号分隔的字符串
# 确保收件人列表不为空
if not recipients_list:
logging.error("收件人列表为空,无法保存邮件")
return False, "收件人列表为空"
# 解析邮件内容
email_subject = message.subject if message.subject else "无主题"
body_text = message.get_body(preferencelist=('plain')).get_content()
received_at = datetime.now().isoformat()
# 存储邮件到 Redis
for recipient in recipients_list:
email_id = f"email:{recipient}:{received_at}"
redis_client.hset(email_id, mapping={
"subject": email_subject,
"sender": sender,
"recipients": recipients,
"body": body_text,
"received_at": received_at
})
logging.info(f"邮件已保存到 Redis: {email_id}")
return True, "邮件已保存到 Redis"
def get_emails_for_mailbox(self, mailbox_id, limit=50, offset=0, unread_only=False):
"""获取指定邮箱的邮件列表"""
try:
# 从 Redis 获取邮件
keys = redis_client.keys(f"email:*")
emails = []
for key in keys:
email_data = redis_client.hgetall(key)
emails.append(email_data)
total = len(emails)
return {
'total': total,
'items': emails[offset:offset + limit]
}
except Exception as e:
logger.error(f"获取邮件列表时出错: {str(e)}")
return {'total': 0, 'items': []}
def get_email_by_id(self, email_id):
"""获取指定ID的邮件详情"""
try:
email_data = redis_client.hgetall(f"email:{email_id}")
if not email_data:
return None
return email_data
except Exception as e:
logger.error(f"获取邮件详情时出错: {str(e)}")
return None
def delete_email(self, email_id):
"""删除指定ID的邮件"""
try:
redis_client.delete(f"email:{email_id}")
return True
except Exception as e:
logger.error(f"删除邮件时出错: {str(e)}")
return False
def get_attachment_content(self, attachment_id):
"""获取附件内容"""
db = self.db_session_factory()
try:
attachment = db.query(Attachment).filter(Attachment.id == attachment_id).first()
if not attachment:
return None
content = attachment.get_content()
return {
'content': content,
'filename': attachment.filename,
'content_type': attachment.content_type
}
except Exception as e:
logger.error(f"获取附件内容时出错: {str(e)}")
return None
finally:
db.close()