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/', 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//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/', 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//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)