• 企业应用中的邮件处理


    邮件发送是一种很常见的应用场景,特别是在企业应用中。

    实际开发中,这块宜独立抽取为公共的方法进行实现,将样式、结构统一处理。下面以Python为例进行简单的介绍:

    1,邮件内容分析:

    一般的邮件,我们可以将展示的内容分为如下5个部分:

    subject,greeting,content,list_data和footer。

    2,样式常量定义

    const.MAIL_FOOTER = (u"<p><span style='font-weight:bold'>P.S. </span><br>"
                             u"本邮件由【堡垒机(CloudSecureMgmt, CSM)】自动发送,如有疑问,"
                             u"请加堡垒机eSpace沟通群:12345678 进行咨询。<br>"
                             u"This mail is sent by CSM system automatically, if any questions, "
                             u"please contact us by joining eSpace group: 12345678 for further learn.</p>")
        const.MAIL_CSM_ADDRESS = u"<p><span style='font-weight:bold'>堡垒机地址:</span>https://csm.demo.com.</p>"
        const.MAIL_TITLE = u"【堡垒机(CSM)知会】"
        const.MAIL_OUTER_TABLE_STYLE = 
            u'align="left" border="0" cellpadding="5" cellspacing="0" width="100%" style="border-collapse: collapse;"'
        const.MAIL_INNER_TABLE_STYLE = 
            u'align="left" border="3" cellpadding="5" cellspacing="0" style="border-collapse: collapse;margin-left:-5px;"'

    3, 底层邮件发送方法:

    def send_mail(mail_title, mail_msg, mail_to):
        """
        发送邮件信息
        :param mail_title: 邮件标题
        :param mail_msg: 邮件内容
        :param mail_to: 收件人
        :return: True or False
        """
        try:
            msg = EmailMessage(mail_title, mail_msg, EMAIL_HOST_USER, mail_to)
            msg.content_subtype = "html"
            msg.send()
            return True
        except Exception as e:
            logger.error(u"邮件发送失败, 错误信息: {}".format(e))
            return False

    4,列表展示的HTML生成代码:

    def build_mail_table(show_name_list, data):
        """
        返回数据展示的HTML表格代码
        :param:
            show_name_list: 对外展示的表头名称列表
            data: 要展示的数据,格式为[tuple]
        """
        show_name_list.insert(0, u"序号")
        for i in range(len(data)):
            temp_data = list(data[i])
            temp_data.insert(0, i + 1)
            data[i] = temp_data
        html_table = u"<table {table_style}> <thead>".format(table_style=const.MAIL_INNER_TABLE_STYLE)
        html_table = u"".join(
            [html_table, u"".join([u"<th>{}</th>".format(name) for name in show_name_list]), u"</thead><tbody>"])
        table_content = u"".join([u"<tr> {row_content} </tr>".format(
            row_content=u"".join([u"<td style='padding:5px 20px;'> {cell_content} </td>".format(
                cell_content=u"{}".format(
                    value)) for value in item])) for item in data])
        html_table = u"".join([html_table, table_content, u"</tbody></table>"])
        return html_table

    5,邮件构建方法:

    def build_and_send_mail(**kwargs):
        """
        提供堡垒机统一的邮件发送方法,
        负责邮件的构建、样式渲染和发送
        :param kwargs:
            subject: 邮件主题, 必选, 注明本邮件的目的, 如:权限过期提醒
            content: 邮件的正文内容, 必选, 如:***正在申请以下服务的成员权限,请登录堡垒机(https://www.huaweicloud.com)查看:
            show_name_list: 表格展示的表头列表,可选, 如:[u"姓名", u"工号", u"电话"]
            data: 要表格形式展示的数据,格式为[tuple], 可选, 注意tuple中的数据顺序要和表头保持一致
            mail_to_list: 收件人地址列表, 必选
        :return: True or False
        """
        if not kwargs.get("subject") or not kwargs.get("content") or not kwargs.get("mail_to_list"):
            logger.error(u"邮件发送失败:必选参数缺失!")
            return False
        mail_title = "{}{}".format(const.MAIL_TITLE, kwargs.get("subject"))
        mail_to = kwargs.get("mail_to_list")
        mail_msg = (u"<table {table_style}><thead>"
                    u"<th style='text-align:left; font-size: 25px'>{greeting}</th></thead><tbody>").format(
            table_style=const.MAIL_OUTER_TABLE_STYLE,
            greeting=u"Hi 亲爱的堡垒机用户, " if len(mail_to) > 1 else (u"Hi {}, ".format(
                User.objects.filter(email=mail_to[0]).first().name
            ))
        )
        mail_msg = u"".join([mail_msg, u"<tr><td><hr /></td></tr>",
                             u"<tr><td>{content}</td></tr>".format(content=kwargs.get("content"))])
        if kwargs.get("show_name_list") and kwargs.get("data"):
            html_table = build_mail_table(kwargs.get("show_name_list"), kwargs.get("data"))
            if html_table:
                mail_msg = u"".join([mail_msg, u"<tr><td>", html_table, u"</td></tr>"])
        mail_msg = u"".join([mail_msg, u"<tr><td><br>", const.MAIL_CSM_ADDRESS, u"</td></tr>",
                             u"<tr><td><hr /></td></tr>", u"<tr><td>",
                             const.MAIL_FOOTER, u"</td></tr></tbody></table>"])
    
        return send_mail(mail_title, mail_msg, mail_to)

    6,调用示范:

    subject = u"用户信息公示"
    content = u"您所需的堡垒机用户信息如下,请查阅:"
    users = models.User.objects.all()[:10]
    show_name_list = [u"姓名", u"工号", u"电话", u"Mail"]
    data = [(user.name, user.username, user.phone, user.email) for user in users]
    mail_to_list = ["demo1@demo.com", "demo2@demo.com"]
    
    if utils.build_and_send_mail(subject=subject, content=content, show_name_list=show_name_list,
                                 data=data, mail_to_list=mail_to_list):
        print("Send mail to {} successfully.".format("yonguo"))
    else:
        print("Failed")

    7,如此便实现了内容和样式的分离。后续如需要改动邮件的结构和样式,只需要维护构建函数即可。

  • 相关阅读:
    【bzoj3782】上学路线 dp+容斥原理+Lucas定理+中国剩余定理
    【bzoj3210】花神的浇花集会 旋转坐标系
    【bzoj3513】[MUTC2013]idiots FFT
    【bzoj1043】[HAOI2008]下落的圆盘 计算几何
    【bzoj2521】[Shoi2010]最小生成树 网络流最小割
    【bzoj4811】[Ynoi2017]由乃的OJ 树链剖分+线段树区间合并
    【bzoj2467】[中山市选2010]生成树 矩阵树定理
    【bzoj1002】[FJOI2007]轮状病毒 矩阵树定理+高精度
    【bzoj4031】[HEOI2015]小Z的房间 矩阵树定理
    【bzoj4292】[PA2015]Równanie 暴力
  • 原文地址:https://www.cnblogs.com/yonguo123/p/9554259.html
Copyright © 2020-2023  润新知