Example #1
0
def tp_send_mail(recipient,
                 message,
                 subject=None,
                 sender=None,
                 cc=None,
                 bcc=None,
                 server=None,
                 port=None,
                 use_ssl=None,
                 username=None,
                 password=None):
    """
    :type recipient: str | list[str]
    :type message: str
    :type subject: str | None
    :type sender: str | None
    :type cc: str | list[str] | None
    :type bcc: str | list[str] | None
    :type server: str | None
    :type port: int | None
    :type use_ssl: bool | None
    :type username: string | None
    :type password: string | None
    :rtype: dict
    """
    sys_smtp = tp_cfg().sys.smtp
    sys_smtp_password = tp_cfg().sys_smtp_password

    _subject = subject if subject is not None else '系统消息'
    _sender = sender if sender is not None else sys_smtp.sender
    _server = server if server is not None else sys_smtp.server
    _port = port if port is not None else sys_smtp.port
    if use_ssl is None:
        _ssl = True if sys_smtp.ssl else False
    else:
        _ssl = use_ssl
    _username = username if username is not None else sys_smtp.sender
    _password = password if password is not None else sys_smtp_password
    _recipients = recipient if type(recipient) == list else [recipient]

    _subject = '[TELEPORT] {}'.format(_subject)

    _smtp = None

    try:
        msg = MIMEMultipart('alternative')
        msg['Subject'] = _sanitize_subject(_subject)
        msg['From'] = _sender
        msg['To'] = ', '.join(_recipients)
        if cc is not None:
            _cc = cc if type(cc) == list else [cc]
            _recipients.extend(_cc)
            msg['Cc'] = ', '.join(_cc)
        if bcc is not None:
            _bcc = bcc if type(bcc) == list else [bcc]
            _recipients.extend(_bcc)
            msg['Bcc'] = ', '.join(_bcc)

        msg.attach(MIMEText(message, 'plain'))
        # msg.attach(MIMEText(html_string, 'html'))

        # 收件人去重
        _recipients = list(set(_recipients))

        dbg_mode, _ = tp_cfg().get_bool('common::debug-mode', False)

        if _ssl:
            _smtp = smtplib.SMTP_SSL(_server, _port, timeout=10.0)
            if dbg_mode:
                _smtp.set_debuglevel(1)
            _smtp.ehlo()
            if (_port == 25 or _port == 587) and _smtp.has_extn("starttls"):
                _smtp.starttls()
        else:
            _smtp = smtplib.SMTP(_server, _port, timeout=10.0)
            if dbg_mode:
                _smtp.set_debuglevel(1)
            _smtp.ehlo()
            if _smtp.has_extn("starttls"):
                try:
                    _smtp.starttls()
                except:
                    pass

        if _password is not None and len(_password) > 0:
            _smtp.login(_username, _password)

        _smtp.set_debuglevel(0)
        send_errors = _smtp.sendmail(_sanitize_address(_sender),
                                     _sanitize_addresses(_recipients),
                                     msg.as_string())

        if len(send_errors) != 0:
            log.e('not all mail send:\n')
            for i in send_errors:
                log.e('  {}, [{}]{}\n'.format(i, send_errors[i][0],
                                              send_errors[i][1]))
            return TPE_FAILED, '无法将邮件发送给部分收件人!'

        return TPE_OK, ''

    except (socket.timeout, socket.gaierror, ConnectionRefusedError,
            smtplib.SMTPServerDisconnected):
        return TPE_FAILED, '无法连接SMTP邮件服务器,请检查服务器地址、端口以及SSL设置!'

    except ssl.SSLError:
        return TPE_FAILED, '无法连接SMTP邮件服务器,请检查服务器端口及SSL设置是否匹配!'

    except smtplib.SMTPAuthenticationError:
        return TPE_FAILED, '无法验证发件人身份,请检查发件人邮箱和密码!'

    except smtplib.SMTPRecipientsRefused as e:
        # {'*****@*****.**': (550, b'Mailbox not found or access denied')}
        x = e.args[0]
        msg = ['发送邮件失败!']
        for i in x:
            msg.append('{}: [{}] {}'.format(i, x[i][0], x[i][1].decode()))
        return TPE_FAILED, '<br/>'.join(msg)

    except smtplib.SMTPException as e:
        return TPE_FAILED, '无法发送邮件:{}'.format(e.__str__())

    except Exception:
        log.e('send mail failed.\n')
        return TPE_FAILED, '无法发送邮件!'