利用 RQ 任务发送电子邮件
不要认为本节偏离主题,我在上面说过,当后台导出任务完成时,将使用包含所有用户动态的 JSON 文件向用户发送电子邮件。 我在 第十章 中构建的电子邮件功能需要通过两种方式进行扩展。 首先,我需要添加对文件附件的支持,以便我可以附加 JSON 文件。 其次, send_email() 函数总是使用后台线程异步发送电子邮件。 当我要从后台任务发送一封电子邮件时(已经是异步的了),基于线程的二级后台任务没有什么意义,所以我需要同时支持同步和异步电子邮件的发送。
幸运的是,Flask-Mail 支持附件,所以我需要做的就是扩展 send_email() 函数的默认关键字参数,然后在 Message 对象中配置它们。 选择在前台发送电子邮件时,我只需要添加一个 sync=True 的关键字参数即可:
app/email.py :发送带附件的邮件。
# ...
def send_email(subject, sender, recipients, text_body, html_body,
attachments=None, sync=False):
msg = Message(subject, sender=sender, recipients=recipients)
msg.body = text_body
msg.html = html_body
if attachments:
for attachment in attachments:
msg.attach(*attachment)
if sync:
mail.send(msg)
else:
Thread(target=send_async_email,
args=(current_app._get_current_object(), msg)).start()
Message 类的 attach() 方法接受三个定义附件的参数:文件名,媒体类型和实际文件数据。 文件名就是收件人看到的与附件关联的名称。 媒体类型定义了这种附件的类型,这有助于电子邮件读者适当地渲染它。 例如,如果你发送 image/png 作为媒体类型,则电子邮件阅读器会知道该附件是一个图像,在这种情况下,它可以显示它。 对于用户动态数据文件,我将使用 JSON 格式,该格式使用 application/json 媒体类型。 最后一个参数包含附件内容的字符串或字节序列。
简单来说, send_email() 的 attachments 参数将成为一个元组列表,每个元组将有三个元素对应于 attach() 的三个参数。 因此,我需要将此列表中的每个元素作为参数发送给 attach() 。 在 Python 中,如果你想将列表或元组中的每个元素作为参数传递给函数,你可以使用 func(*args) 将这个列表或元祖解包成函数中的多个参数,而不必枯燥地一个个地传递,如 func(args[0], args[1], args[2]) 。 例如,如果你有一个列表 args = [1, 'foo'] , func(*args) 将会传递两个参数,就和你调用 func(1, 'foo') 一样。 如果没有 * ,调用将会传入一个参数,即 args 列表。
至于电子邮件的同步发送,我需要做的就是,当 sync 是 True 的时候恢复成调用 mail.send(msg) 。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论