mower-ng/mower/utils/email.py
2024-12-03 09:36:51 +08:00

108 lines
3.5 KiB
Python

import smtplib
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from threading import Thread
from time import sleep
from typing import Literal, Optional
from jinja2 import Environment, FileSystemLoader, select_autoescape
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.image import img2bytes
from mower.utils.log import logger
from mower.utils.path import get_path
template_dir = get_path("@install/mower/templates")
env = Environment(loader=FileSystemLoader(template_dir), autoescape=select_autoescape())
task_template = env.get_template("task.html")
drop_template = env.get_template("drop.html")
recruit_template = env.get_template("recruit_template.html")
recruit_rarity = env.get_template("recruit_rarity.html")
report_template = env.get_template("report_template.html")
assistants_template = env.get_template("assistants.html")
class Email:
def __init__(self, body, subject, attach_image):
conf = config.conf
msg = MIMEMultipart()
msg.attach(MIMEText(body, "html"))
msg["Subject"] = subject
msg["From"] = conf.account
msg["To"] = ", ".join(conf.recipient)
if attach_image is not None:
attachment = img2bytes(attach_image)
image_content = MIMEImage(attachment.tobytes())
image_content.add_header(
"Content-Disposition", "attachment", filename="image.jpg"
)
msg.attach(image_content)
self.msg = msg
if conf.custom_smtp_server.enable:
self.smtp_server = conf.custom_smtp_server.server
self.port = conf.custom_smtp_server.ssl_port
self.encryption = conf.custom_smtp_server.encryption
else:
self.smtp_server = "smtp.qq.com"
self.port = 465
self.encryption = "tls"
def send(self):
if self.encryption == "starttls":
s = smtplib.SMTP(self.smtp_server, self.port, timeout=10)
s.starttls()
else:
s = smtplib.SMTP_SSL(self.smtp_server, self.port, timeout=10)
conf = config.conf
s.login(conf.account, conf.pass_code)
recipient = conf.recipient or [conf.account]
s.send_message(self.msg, conf.account, recipient)
s.quit()
def send_message(
body="",
subject="",
level: Literal["INFO", "WARNING", "ERROR"] = "INFO",
attach_image: Optional[tp.Image] = None,
):
"""异步发送邮件
Args:
body: 邮件内容
subject: 邮件标题
level: 通知等级
attach_image: 图片附件
"""
conf = config.conf
if not conf.mail_enable:
return
if conf.notification_level == "WARNING" and level == "INFO":
return
if conf.notification_level == "ERROR" and level != "ERROR":
return
if subject == "":
subject = body.split("\n")[0].strip()
subject = conf.mail_subject + subject
email = Email(body, subject, attach_image)
def send_message_sync(email):
for i in range(3):
try:
email.send()
break
except Exception as e:
logger.exception("邮件发送失败:" + str(e))
sleep(2**i)
Thread(target=send_message_sync, args=(email,)).start()
def notify(msg: str, level: Literal["INFO", "WARNING", "ERROR"] = "INFO"):
getattr(logger, level.lower())(msg)
send_message(msg, level=level, attach_image=config.recog.img)