198 lines
6.9 KiB
Python
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 |