初始化提交,包含完整的邮件系统代码
This commit is contained in:
23
app/api/__init__.py
Normal file
23
app/api/__init__.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# API模块初始化文件
|
||||
from flask import Blueprint
|
||||
import logging
|
||||
|
||||
# 创建API蓝图
|
||||
api_bp = Blueprint('api', __name__, url_prefix='/api')
|
||||
|
||||
# 注册默认路由
|
||||
@api_bp.route('/')
|
||||
def index():
|
||||
return {
|
||||
'name': 'Email System API',
|
||||
'version': '1.0.0',
|
||||
'status': 'running'
|
||||
}
|
||||
|
||||
# 导入并合并所有API路由
|
||||
# 为避免可能的文件读取问题,改为从routes.py模块中导入所有路由定义
|
||||
try:
|
||||
from .routes import *
|
||||
except Exception as e:
|
||||
logging.error(f"导入API路由时出错: {str(e)}")
|
||||
raise
|
||||
BIN
app/api/domain_routes.py
Normal file
BIN
app/api/domain_routes.py
Normal file
Binary file not shown.
198
app/api/email_routes.py
Normal file
198
app/api/email_routes.py
Normal file
@@ -0,0 +1,198 @@
|
||||
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
|
||||
206
app/api/mailbox_routes.py
Normal file
206
app/api/mailbox_routes.py
Normal file
@@ -0,0 +1,206 @@
|
||||
from flask import request, jsonify, current_app
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
import random
|
||||
import string
|
||||
|
||||
from . import api_bp
|
||||
from ..models import get_session, Domain, Mailbox
|
||||
|
||||
# 获取所有邮箱
|
||||
@api_bp.route('/mailboxes', methods=['GET'])
|
||||
def get_mailboxes():
|
||||
"""获取所有邮箱列表"""
|
||||
try:
|
||||
page = int(request.args.get('page', 1))
|
||||
limit = int(request.args.get('limit', 50))
|
||||
offset = (page - 1) * limit
|
||||
|
||||
db = get_session()
|
||||
try:
|
||||
# 查询总数
|
||||
total = db.query(Mailbox).count()
|
||||
|
||||
# 获取分页数据
|
||||
mailboxes = db.query(Mailbox).order_by(Mailbox.created_at.desc()) \
|
||||
.limit(limit) \
|
||||
.offset(offset) \
|
||||
.all()
|
||||
|
||||
# 转换为字典列表
|
||||
result = {
|
||||
'total': total,
|
||||
'page': page,
|
||||
'limit': limit,
|
||||
'mailboxes': [mailbox.to_dict() for mailbox in mailboxes]
|
||||
}
|
||||
|
||||
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('/mailboxes', methods=['POST'])
|
||||
def create_mailbox():
|
||||
"""创建新邮箱"""
|
||||
try:
|
||||
data = request.json
|
||||
|
||||
# 验证必要参数
|
||||
if not data or 'domain_id' not in data:
|
||||
return jsonify({'error': '缺少必要参数'}), 400
|
||||
|
||||
db = get_session()
|
||||
try:
|
||||
# 查询域名是否存在
|
||||
domain = db.query(Domain).filter_by(id=data['domain_id'], active=True).first()
|
||||
if not domain:
|
||||
return jsonify({'error': '指定的域名不存在或未激活'}), 404
|
||||
|
||||
# 生成或使用给定地址
|
||||
if 'address' not in data or not data['address']:
|
||||
# 生成随机地址
|
||||
address = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
|
||||
else:
|
||||
address = data['address']
|
||||
|
||||
# 创建邮箱
|
||||
mailbox = Mailbox(
|
||||
address=address,
|
||||
domain_id=domain.id,
|
||||
description=data.get('description', ''),
|
||||
active=True
|
||||
)
|
||||
|
||||
db.add(mailbox)
|
||||
db.commit()
|
||||
|
||||
return jsonify({
|
||||
'message': '邮箱创建成功',
|
||||
'mailbox': mailbox.to_dict()
|
||||
}), 201
|
||||
except IntegrityError:
|
||||
db.rollback()
|
||||
return jsonify({'error': '邮箱地址已存在'}), 409
|
||||
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('/mailboxes/batch', methods=['POST'])
|
||||
def batch_create_mailboxes():
|
||||
"""批量创建邮箱"""
|
||||
try:
|
||||
data = request.json
|
||||
|
||||
# 验证必要参数
|
||||
if not data or 'domain_id' not in data or 'count' not in data:
|
||||
return jsonify({'error': '缺少必要参数'}), 400
|
||||
|
||||
domain_id = data['domain_id']
|
||||
count = min(int(data['count']), 100) # 限制最大数量为100
|
||||
prefix = data.get('prefix', '')
|
||||
|
||||
db = get_session()
|
||||
try:
|
||||
# 查询域名是否存在
|
||||
domain = db.query(Domain).filter_by(id=domain_id, active=True).first()
|
||||
if not domain:
|
||||
return jsonify({'error': '指定的域名不存在或未激活'}), 404
|
||||
|
||||
created_mailboxes = []
|
||||
|
||||
# 批量创建
|
||||
for _ in range(count):
|
||||
# 生成随机地址
|
||||
if prefix:
|
||||
address = f"{prefix}{random.randint(1000, 9999)}"
|
||||
else:
|
||||
address = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
|
||||
|
||||
# 尝试创建,如果地址已存在则重试
|
||||
retries = 0
|
||||
while retries < 3: # 最多尝试3次
|
||||
try:
|
||||
mailbox = Mailbox(
|
||||
address=address,
|
||||
domain_id=domain.id,
|
||||
active=True
|
||||
)
|
||||
|
||||
db.add(mailbox)
|
||||
db.flush() # 验证但不提交
|
||||
created_mailboxes.append(mailbox)
|
||||
break
|
||||
except IntegrityError:
|
||||
db.rollback()
|
||||
# 地址已存在,重新生成
|
||||
address = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
|
||||
retries += 1
|
||||
|
||||
# 提交所有更改
|
||||
db.commit()
|
||||
|
||||
return jsonify({
|
||||
'message': f'成功创建 {len(created_mailboxes)} 个邮箱',
|
||||
'mailboxes': [mailbox.to_dict() for mailbox in created_mailboxes]
|
||||
}), 201
|
||||
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('/mailboxes/<int:mailbox_id>', methods=['GET'])
|
||||
def get_mailbox(mailbox_id):
|
||||
"""获取指定ID的邮箱信息"""
|
||||
try:
|
||||
db = get_session()
|
||||
try:
|
||||
mailbox = db.query(Mailbox).filter_by(id=mailbox_id).first()
|
||||
|
||||
if not mailbox:
|
||||
return jsonify({'error': '邮箱不存在'}), 404
|
||||
|
||||
return jsonify(mailbox.to_dict()), 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('/mailboxes/<int:mailbox_id>', methods=['DELETE'])
|
||||
def delete_mailbox(mailbox_id):
|
||||
"""删除指定ID的邮箱"""
|
||||
try:
|
||||
db = get_session()
|
||||
try:
|
||||
mailbox = db.query(Mailbox).filter_by(id=mailbox_id).first()
|
||||
|
||||
if not mailbox:
|
||||
return jsonify({'error': '邮箱不存在'}), 404
|
||||
|
||||
db.delete(mailbox)
|
||||
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
|
||||
341
app/api/routes.py
Normal file
341
app/api/routes.py
Normal file
@@ -0,0 +1,341 @@
|
||||
from flask import Blueprint, request, jsonify, current_app
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
import os
|
||||
import time
|
||||
import psutil
|
||||
import sys
|
||||
import platform
|
||||
from sqlalchemy import func
|
||||
from ..models import get_session, Domain, Mailbox, Email
|
||||
from ..services import get_smtp_server, get_email_processor
|
||||
|
||||
api_bp = Blueprint('api', __name__, url_prefix='/api')
|
||||
|
||||
|
||||
@api_bp.route('/domains', methods=['GET'])
|
||||
def get_domains():
|
||||
"""获取所有可用域名"""
|
||||
db = get_session()
|
||||
try:
|
||||
domains = db.query(Domain).filter_by(active=True).all()
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'domains': [domain.to_dict() for domain in domains]
|
||||
})
|
||||
except Exception as e:
|
||||
current_app.logger.exception(f"获取域名失败: {str(e)}")
|
||||
return jsonify({'success': False, 'error': '获取域名失败'}), 500
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@api_bp.route('/domains', methods=['POST'])
|
||||
def create_domain():
|
||||
"""创建新域名"""
|
||||
data = request.json
|
||||
if not data or 'name' not in data:
|
||||
return jsonify({'success': False, 'error': '缺少必要字段'}), 400
|
||||
|
||||
db = get_session()
|
||||
try:
|
||||
# 检查域名是否已存在
|
||||
domain_exists = db.query(Domain).filter_by(name=data['name']).first()
|
||||
if domain_exists:
|
||||
return jsonify({'success': False, 'error': '域名已存在'}), 400
|
||||
|
||||
# 创建新域名
|
||||
domain = Domain(
|
||||
name=data['name'],
|
||||
description=data.get('description', ''),
|
||||
active=data.get('active', True)
|
||||
)
|
||||
db.add(domain)
|
||||
db.commit()
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': '域名创建成功',
|
||||
'domain': domain.to_dict()
|
||||
})
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
current_app.logger.exception(f"创建域名失败: {str(e)}")
|
||||
return jsonify({'success': False, 'error': '创建域名失败'}), 500
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@api_bp.route('/mailboxes', methods=['GET'])
|
||||
def get_mailboxes():
|
||||
"""获取所有邮箱"""
|
||||
db = get_session()
|
||||
try:
|
||||
mailboxes = db.query(Mailbox).all()
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'mailboxes': [mailbox.to_dict() for mailbox in mailboxes]
|
||||
})
|
||||
except Exception as e:
|
||||
current_app.logger.exception(f"获取邮箱失败: {str(e)}")
|
||||
return jsonify({'success': False, 'error': '获取邮箱失败'}), 500
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@api_bp.route('/mailboxes', methods=['POST'])
|
||||
def create_mailbox():
|
||||
"""创建新邮箱"""
|
||||
data = request.json
|
||||
if not data or 'address' not in data or 'domain_id' not in data:
|
||||
return jsonify({'success': False, 'error': '缺少必要字段'}), 400
|
||||
|
||||
db = get_session()
|
||||
try:
|
||||
# 检查域名是否存在
|
||||
domain = db.query(Domain).filter_by(id=data['domain_id'], active=True).first()
|
||||
if not domain:
|
||||
return jsonify({'success': False, 'error': '域名不存在或未激活'}), 400
|
||||
|
||||
# 检查邮箱是否已存在
|
||||
mailbox_exists = db.query(Mailbox).filter_by(
|
||||
address=data['address'], domain_id=data['domain_id']).first()
|
||||
if mailbox_exists:
|
||||
return jsonify({'success': False, 'error': '邮箱已存在'}), 400
|
||||
|
||||
# 创建新邮箱
|
||||
mailbox = Mailbox(
|
||||
address=data['address'],
|
||||
domain_id=data['domain_id'],
|
||||
description=data.get('description', ''),
|
||||
active=data.get('active', True)
|
||||
)
|
||||
db.add(mailbox)
|
||||
db.commit()
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': '邮箱创建成功',
|
||||
'mailbox': mailbox.to_dict()
|
||||
})
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
current_app.logger.exception(f"创建邮箱失败: {str(e)}")
|
||||
return jsonify({'success': False, 'error': '创建邮箱失败'}), 500
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@api_bp.route('/mailboxes/batch', methods=['POST'])
|
||||
def batch_create_mailboxes():
|
||||
"""批量创建邮箱"""
|
||||
data = request.json
|
||||
if not data or 'domain_id' not in data or 'usernames' not in data or not isinstance(data['usernames'], list):
|
||||
return jsonify({'success': False, 'error': '缺少必要字段或格式不正确'}), 400
|
||||
|
||||
domain_id = data['domain_id']
|
||||
usernames = data['usernames']
|
||||
description = data.get('description', '')
|
||||
|
||||
db = get_session()
|
||||
try:
|
||||
# 检查域名是否存在
|
||||
domain = db.query(Domain).filter_by(id=domain_id, active=True).first()
|
||||
if not domain:
|
||||
return jsonify({'success': False, 'error': '域名不存在或未激活'}), 400
|
||||
|
||||
created_mailboxes = []
|
||||
existed_mailboxes = []
|
||||
|
||||
for username in usernames:
|
||||
# 检查邮箱是否已存在
|
||||
mailbox_exists = db.query(Mailbox).filter_by(
|
||||
username=username, domain_id=domain_id).first()
|
||||
if mailbox_exists:
|
||||
existed_mailboxes.append(username)
|
||||
continue
|
||||
|
||||
# 创建新邮箱
|
||||
mailbox = Mailbox(
|
||||
username=username,
|
||||
domain_id=domain_id,
|
||||
description=description,
|
||||
active=True
|
||||
)
|
||||
db.add(mailbox)
|
||||
created_mailboxes.append(username)
|
||||
|
||||
db.commit()
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': f'成功创建 {len(created_mailboxes)} 个邮箱,{len(existed_mailboxes)} 个已存在',
|
||||
'created': created_mailboxes,
|
||||
'existed': existed_mailboxes
|
||||
})
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
current_app.logger.exception(f"批量创建邮箱失败: {str(e)}")
|
||||
return jsonify({'success': False, 'error': '批量创建邮箱失败'}), 500
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@api_bp.route('/mailboxes/<int:mailbox_id>', methods=['GET'])
|
||||
def get_mailbox(mailbox_id):
|
||||
"""获取特定邮箱的信息"""
|
||||
db = get_session()
|
||||
try:
|
||||
mailbox = db.query(Mailbox).filter_by(id=mailbox_id).first()
|
||||
if not mailbox:
|
||||
return jsonify({'success': False, 'error': '邮箱不存在'}), 404
|
||||
|
||||
# 更新最后访问时间
|
||||
mailbox.last_accessed = datetime.utcnow()
|
||||
db.commit()
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'mailbox': mailbox.to_dict()
|
||||
})
|
||||
except Exception as e:
|
||||
current_app.logger.exception(f"获取邮箱信息失败: {str(e)}")
|
||||
return jsonify({'success': False, 'error': '获取邮箱信息失败'}), 500
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@api_bp.route('/mailboxes/<int:mailbox_id>/emails', methods=['GET'])
|
||||
def get_emails(mailbox_id):
|
||||
"""获取邮箱中的所有邮件"""
|
||||
db = get_session()
|
||||
try:
|
||||
mailbox = db.query(Mailbox).filter_by(id=mailbox_id).first()
|
||||
if not mailbox:
|
||||
return jsonify({'success': False, 'error': '邮箱不存在'}), 404
|
||||
|
||||
# 更新最后访问时间
|
||||
mailbox.last_accessed = datetime.utcnow()
|
||||
db.commit()
|
||||
|
||||
emails = db.query(Email).filter_by(mailbox_id=mailbox_id).order_by(Email.received_at.desc()).all()
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'emails': [email.to_dict() for email in emails]
|
||||
})
|
||||
except Exception as e:
|
||||
current_app.logger.exception(f"获取邮件失败: {str(e)}")
|
||||
return jsonify({'success': False, 'error': '获取邮件失败'}), 500
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@api_bp.route('/emails/<int:email_id>', methods=['GET'])
|
||||
def get_email(email_id):
|
||||
"""获取特定邮件的详细内容"""
|
||||
db = get_session()
|
||||
try:
|
||||
email = db.query(Email).filter_by(id=email_id).first()
|
||||
if not email:
|
||||
return jsonify({'success': False, 'error': '邮件不存在'}), 404
|
||||
|
||||
# 标记为已读
|
||||
if not email.read:
|
||||
email.read = True
|
||||
db.commit()
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'email': email.to_dict()
|
||||
})
|
||||
except Exception as e:
|
||||
current_app.logger.exception(f"获取邮件详情失败: {str(e)}")
|
||||
return jsonify({'success': False, 'error': '获取邮件详情失败'}), 500
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@api_bp.route('/emails/<int:email_id>/verification', methods=['GET'])
|
||||
def get_verification_info(email_id):
|
||||
"""获取邮件中的验证信息(链接和验证码)"""
|
||||
db = get_session()
|
||||
try:
|
||||
email = db.query(Email).filter_by(id=email_id).first()
|
||||
if not email:
|
||||
return jsonify({'success': False, 'error': '邮件不存在'}), 404
|
||||
|
||||
verification_links = json.loads(email.verification_links) if email.verification_links else []
|
||||
verification_codes = json.loads(email.verification_codes) if email.verification_codes else []
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'email_id': email_id,
|
||||
'verification_links': verification_links,
|
||||
'verification_codes': verification_codes
|
||||
})
|
||||
except Exception as e:
|
||||
current_app.logger.exception(f"获取验证信息失败: {str(e)}")
|
||||
return jsonify({'success': False, 'error': '获取验证信息失败'}), 500
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@api_bp.route('/status', methods=['GET'])
|
||||
def system_status():
|
||||
"""获取系统状态"""
|
||||
session = get_session()
|
||||
|
||||
# 获取基本统计信息
|
||||
domain_count = session.query(func.count(Domain.id)).scalar()
|
||||
mailbox_count = session.query(func.count(Mailbox.id)).scalar()
|
||||
email_count = session.query(func.count(Email.id)).scalar()
|
||||
|
||||
# 获取最近24小时的邮件数量
|
||||
recent_emails = session.query(func.count(Email.id)).filter(
|
||||
Email.received_at > datetime.now() - timedelta(hours=24)
|
||||
).scalar()
|
||||
|
||||
# 获取系统资源信息
|
||||
cpu_percent = psutil.cpu_percent(interval=0.5)
|
||||
memory = psutil.virtual_memory()
|
||||
disk = psutil.disk_usage('/')
|
||||
|
||||
# 获取服务状态
|
||||
smtp_server = get_smtp_server()
|
||||
email_processor = get_email_processor()
|
||||
|
||||
smtp_status = "running" if smtp_server and smtp_server.controller else "stopped"
|
||||
processor_status = "running" if email_processor and email_processor.is_running else "stopped"
|
||||
|
||||
# 构建响应
|
||||
status = {
|
||||
"system": {
|
||||
"uptime": round(time.time() - psutil.boot_time()),
|
||||
"time": datetime.now().isoformat(),
|
||||
"platform": platform.platform(),
|
||||
"python_version": sys.version
|
||||
},
|
||||
"resources": {
|
||||
"cpu_percent": cpu_percent,
|
||||
"memory_percent": memory.percent,
|
||||
"memory_used": memory.used,
|
||||
"memory_total": memory.total,
|
||||
"disk_percent": disk.percent,
|
||||
"disk_used": disk.used,
|
||||
"disk_total": disk.total
|
||||
},
|
||||
"application": {
|
||||
"domain_count": domain_count,
|
||||
"mailbox_count": mailbox_count,
|
||||
"email_count": email_count,
|
||||
"recent_emails_24h": recent_emails,
|
||||
"storage_path": os.path.abspath("email_data"),
|
||||
"services": {
|
||||
"smtp_server": smtp_status,
|
||||
"email_processor": processor_status
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return jsonify(status)
|
||||
Reference in New Issue
Block a user