forked from jly8866/archer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsendmail.py
96 lines (80 loc) · 3.66 KB
/
sendmail.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# -*- coding: UTF-8 -*-
import traceback
from multiprocessing import Process
import email
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import smtplib
from django.conf import settings
import logging
logger = logging.getLogger('default')
class MailSender(object):
def __init__(self):
try:
self.MAIL_REVIEW_SMTP_SERVER = getattr(settings, 'MAIL_REVIEW_SMTP_SERVER')
self.MAIL_REVIEW_SMTP_PORT = int(getattr(settings, 'MAIL_REVIEW_SMTP_PORT'))
self.MAIL_REVIEW_FROM_ADDR = getattr(settings, 'MAIL_REVIEW_FROM_ADDR')
self.MAIL_REVIEW_FROM_PASSWORD = getattr(settings, 'MAIL_REVIEW_FROM_PASSWORD')
self.SSL = getattr(settings, 'MAIL_SSL')
except AttributeError as a:
print("Error: %s" % a)
except ValueError as v:
print("Error: %s" % v)
def _format_addr(self, s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
def _add_attachment(self, filename):
'''''
添加附件
'''
file_msg = email.mime.base.MIMEBase('application', 'octet-stream')
file_msg.set_payload(open(filename, 'rb').read())
# 附件如果有中文会出现乱码问题,加入gbk
file_msg.add_header('Content-Disposition', 'attachment', filename=('gbk', '', filename.split('/')[-1]))
encoders.encode_base64(file_msg)
return file_msg
def _send(self, strTitle, strContent, listToAddr, **kwargs):
'''''
发送邮件
'''
# 构造MIMEMultipart对象做为根容器
main_msg = email.mime.multipart.MIMEMultipart()
# 添加文本内容
text_msg = email.mime.text.MIMEText(strContent, 'plain', 'utf-8')
main_msg.attach(text_msg)
# 添加附件
filename_list = kwargs.get('filename_list')
if filename_list:
for filename in kwargs['filename_list']:
file_msg = self._add_attachment(filename)
main_msg.attach(file_msg)
# 收发件人地址和邮件标题:
main_msg['From'] = formataddr(["archer 通知", self.MAIL_REVIEW_FROM_ADDR])
main_msg['To'] = ','.join(listToAddr)
listCcAddr = kwargs.get('listCcAddr')
if listCcAddr:
main_msg['Cc'] = ', '.join(kwargs['listCcAddr'])
listAddr = listToAddr + listCcAddr
else:
listAddr = listToAddr
main_msg['Subject'] = Header(strTitle, "utf-8").encode()
main_msg['Date'] = email.utils.formatdate()
if self.SSL:
server = smtplib.SMTP_SSL(self.MAIL_REVIEW_SMTP_SERVER, self.MAIL_REVIEW_SMTP_PORT) # SMTP协议默认SSL端口是465
else:
server = smtplib.SMTP(self.MAIL_REVIEW_SMTP_SERVER, self.MAIL_REVIEW_SMTP_PORT) # SMTP协议默认端口是25
# server.set_debuglevel(1)
# 如果提供的密码为空,则不需要登录SMTP server
if self.MAIL_REVIEW_FROM_PASSWORD != '':
server.login(self.MAIL_REVIEW_FROM_ADDR, self.MAIL_REVIEW_FROM_PASSWORD)
sendResult = server.sendmail(self.MAIL_REVIEW_FROM_ADDR, listAddr, main_msg.as_string())
server.quit()
# 调用方应该调用此方法,采用子进程方式异步阻塞地发送邮件,避免邮件服务挂掉影响archer主服务
def sendEmail(self, strTitle, strContent, listToAddr, **kwargs):
try:
p = Process(target=self._send, args=(strTitle, strContent, listToAddr), kwargs=kwargs)
p.start()
except Exception:
logger.error(traceback.format_exc())