zoukankan      html  css  js  c++  java
  • 企业应用中的邮件处理

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

    实际开发中,这块宜独立抽取为公共的方法进行实现,将样式、结构统一处理。下面以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,如此便实现了内容和样式的分离。后续如需要改动邮件的结构和样式,只需要维护构建函数即可。

  • 相关阅读:
    tensorflow 2.0 学习 (十) 拟合与过拟合问题
    tensorflow 2.0 学习 (九) tensorboard可视化功能认识
    tensorflow 2.0 学习 (八) keras模块的认识
    tensorflow 2.0 学习 (七) 反向传播代码逐步实现
    tensorflow 2.0 学习 (六) Himmelblua函数求极值
    tensorflow 2.0 学习 (五)MPG全连接网络训练与测试
    arp协议简单介绍
    Pthread spinlock自旋锁
    线程和进程状态
    内核态(内核空间)和用户态(用户空间)的区别和联系·
  • 原文地址:https://www.cnblogs.com/yonguo123/p/9554259.html
Copyright © 2011-2022 走看看