mirror of
https://github.com/fastapi-practices/fastapi_best_architecture.git
synced 2026-03-13 09:31:31 +08:00
* Update user and login security configs * Optimize some code definitions * Update config comments * Update the captcha check * Update the config plugin sql scripts * Add user password history model to init * Fix some logic errors * Add last_password_changed_time to user sql * Fix user update password * Fix the dynamic config check * Update the user sql style
74 lines
2.2 KiB
Python
74 lines
2.2 KiB
Python
from email.mime.multipart import MIMEMultipart
|
|
from email.mime.text import MIMEText
|
|
|
|
from aiosmtplib import SMTP
|
|
from anyio import open_file
|
|
from jinja2 import Template
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from backend.common.log import log
|
|
from backend.core.conf import settings
|
|
from backend.core.path_conf import PLUGIN_DIR
|
|
from backend.utils.dynamic_config import load_email_config
|
|
from backend.utils.timezone import timezone
|
|
|
|
|
|
async def render_message(subject: str, from_header: str, content: str | dict, template: str | None) -> bytes:
|
|
"""
|
|
渲染邮件内容
|
|
|
|
:param subject: 邮件内容主题
|
|
:param from_header: 邮件来源
|
|
:param content: 邮件内容
|
|
:param template: 邮件内容模板
|
|
:return:
|
|
"""
|
|
message = MIMEMultipart()
|
|
message['Subject'] = subject
|
|
message['From'] = from_header
|
|
message['date'] = timezone.now().strftime('%a, %d %b %Y %H:%M:%S %z')
|
|
|
|
if template:
|
|
async with await open_file(PLUGIN_DIR / 'email' / 'templates' / template, encoding='utf-8') as f:
|
|
html = Template(await f.read(), enable_async=True)
|
|
mail_body = MIMEText(await html.render_async(**content), 'html', 'utf-8')
|
|
else:
|
|
mail_body = MIMEText(content, 'plain', 'utf-8')
|
|
|
|
message.attach(mail_body)
|
|
|
|
return message.as_bytes()
|
|
|
|
|
|
async def send_email(
|
|
db: AsyncSession,
|
|
recipients: str | list[str],
|
|
subject: str,
|
|
content: str | dict,
|
|
template: str | None = None,
|
|
) -> None:
|
|
"""
|
|
发送电子邮件
|
|
|
|
:param db: 数据库会话
|
|
:param recipients: 邮件接收者
|
|
:param subject: 邮件内容主题
|
|
:param content: 邮件内容
|
|
:param template: 邮件内容模板
|
|
:return:
|
|
"""
|
|
await load_email_config(db)
|
|
|
|
try:
|
|
message = await render_message(subject, settings.EMAIL_USERNAME, content, template)
|
|
smtp_client = SMTP(
|
|
hostname=settings.EMAIL_HOST,
|
|
port=settings.EMAIL_PORT,
|
|
use_tls=settings.EMAIL_SSL,
|
|
)
|
|
async with smtp_client:
|
|
await smtp_client.login(settings.EMAIL_USERNAME, settings.EMAIL_PASSWORD)
|
|
await smtp_client.sendmail(settings.EMAIL_USERNAME, recipients, message)
|
|
except Exception as e:
|
|
log.error(f'电子邮件发送失败:{e}')
|