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()