Files
emailsystem/app/api/email_routes.py
2025-02-25 19:50:00 +08:00

198 lines
6.9 KiB
Python

from flask import request, jsonify, current_app, send_file
from io import BytesIO
import time
from . import api_bp
from ..models import get_session, Email, Mailbox
# 获取邮箱的所有邮件
@api_bp.route('/mailboxes/<int:mailbox_id>/emails', methods=['GET'])
def get_mailbox_emails(mailbox_id):
"""获取指定邮箱的所有邮件"""
try:
page = int(request.args.get('page', 1))
limit = int(request.args.get('limit', 50))
unread_only = request.args.get('unread_only', 'false').lower() == 'true'
offset = (page - 1) * limit
db = get_session()
try:
# 检查邮箱是否存在
mailbox = db.query(Mailbox).filter_by(id=mailbox_id).first()
if not mailbox:
return jsonify({'error': '邮箱不存在'}), 404
# 查询邮件
query = db.query(Email).filter(Email.mailbox_id == mailbox_id)
if unread_only:
query = query.filter(Email.read == False)
# 获取总数
total = query.count()
# 分页获取邮件
emails = query.order_by(Email.received_at.desc()) \
.limit(limit) \
.offset(offset) \
.all()
# 返回结果
result = {
'total': total,
'page': page,
'limit': limit,
'emails': [email.to_dict() for email in emails]
}
return jsonify(result), 200
finally:
db.close()
except Exception as e:
current_app.logger.error(f"获取邮件列表出错: {str(e)}")
return jsonify({'error': '获取邮件列表失败', 'details': str(e)}), 500
# 获取特定邮件详情
@api_bp.route('/emails/<int:email_id>', methods=['GET'])
def get_email(email_id):
"""获取特定邮件的详细信息"""
try:
mark_as_read = request.args.get('mark_as_read', 'true').lower() == 'true'
db = get_session()
try:
email = db.query(Email).filter_by(id=email_id).first()
if not email:
return jsonify({'error': '邮件不存在'}), 404
# 标记为已读
if mark_as_read and not email.read:
email.read = True
db.commit()
# 构建详细响应
result = email.to_dict()
result['body_text'] = email.body_text
result['body_html'] = email.body_html
# 获取附件信息
attachments = []
for attachment in email.attachments:
attachments.append({
'id': attachment.id,
'filename': attachment.filename,
'content_type': attachment.content_type,
'size': attachment.size
})
result['attachments'] = attachments
return jsonify(result), 200
finally:
db.close()
except Exception as e:
current_app.logger.error(f"获取邮件详情出错: {str(e)}")
return jsonify({'error': '获取邮件详情失败', 'details': str(e)}), 500
# 删除邮件
@api_bp.route('/emails/<int:email_id>', methods=['DELETE'])
def delete_email(email_id):
"""删除特定邮件"""
try:
db = get_session()
try:
email = db.query(Email).filter_by(id=email_id).first()
if not email:
return jsonify({'error': '邮件不存在'}), 404
db.delete(email)
db.commit()
return jsonify({'message': '邮件已删除'}), 200
except Exception as e:
db.rollback()
raise
finally:
db.close()
except Exception as e:
current_app.logger.error(f"删除邮件出错: {str(e)}")
return jsonify({'error': '删除邮件失败', 'details': str(e)}), 500
# 下载附件
@api_bp.route('/attachments/<int:attachment_id>', methods=['GET'])
def download_attachment(attachment_id):
"""下载特定的附件"""
try:
from ..models import Attachment
db = get_session()
try:
attachment = db.query(Attachment).filter_by(id=attachment_id).first()
if not attachment:
return jsonify({'error': '附件不存在'}), 404
# 获取附件内容
content = attachment.get_content()
if not content:
return jsonify({'error': '附件内容不可用'}), 404
# 创建内存文件对象
file_obj = BytesIO(content)
# 返回文件下载响应
return send_file(
file_obj,
mimetype=attachment.content_type,
as_attachment=True,
download_name=attachment.filename
)
finally:
db.close()
except Exception as e:
current_app.logger.error(f"下载附件出错: {str(e)}")
return jsonify({'error': '下载附件失败', 'details': str(e)}), 500
# 获取最新邮件 (轮询API)
@api_bp.route('/mailboxes/<int:mailbox_id>/poll', methods=['GET'])
def poll_new_emails(mailbox_id):
"""轮询指定邮箱的新邮件"""
try:
# 获取上次检查时间
last_check = request.args.get('last_check')
if last_check:
try:
last_check_time = float(last_check)
except ValueError:
return jsonify({'error': '无效的last_check参数'}), 400
else:
last_check_time = time.time() - 300 # 默认检查最近5分钟
db = get_session()
try:
# 检查邮箱是否存在
mailbox = db.query(Mailbox).filter_by(id=mailbox_id).first()
if not mailbox:
return jsonify({'error': '邮箱不存在'}), 404
# 查询新邮件
new_emails = db.query(Email).filter(
Email.mailbox_id == mailbox_id,
Email.received_at >= time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(last_check_time))
).order_by(Email.received_at.desc()).all()
# 返回结果
result = {
'mailbox_id': mailbox_id,
'count': len(new_emails),
'emails': [email.to_dict() for email in new_emails],
'timestamp': time.time()
}
return jsonify(result), 200
finally:
db.close()
except Exception as e:
current_app.logger.error(f"轮询新邮件出错: {str(e)}")
return jsonify({'error': '轮询新邮件失败', 'details': str(e)}), 500