Python implements asynchronous mail sending service based on smtplib

Source: Internet
Author: User
Tags ssl connection

Python implements asynchronous mail sending service based on smtplib

This article mainly introduces Python's implementation of asynchronous mail sending service based on smtplib. For more information, see

It is made based on the smtplib package. However, in practice, it is found that an unknown smtplib is not a pitfall. When the network is disconnected, a socket is thrown when an email is sent. gaierror exception, but this exception is not caught in smtplib, causing the program to terminate due to this exception. Therefore, the Code processes this exception to ensure that no exception is terminated.

?

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

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

#! /Usr/bin/env python

#-*-Coding: UTF-8 -*-

 

_ Author _ = 'zoa chou'

# See http://www.mudoom.com/Article/show/id/29.html for detail

 

Import logging

Import smtplib

Import mimetypes

Import socket

From email import encoders

From email. header import Header

From email. mime. text import MIMEText, MIMENonMultipart

From email. mime. base import MIMEBase

From email. utils import parseaddr, formataddr

 

 

Class Mailer (object ):

Def _ init _ (self ):

Pass

 

Def send_mail (self, smtp_server, from_address, to_address, subject, body, files = None ):

"""

Main email sending program

: Param smtp_server: dict Mail Server Settings

: Keyword host: string smtp server address

: Keyword port: int smtp server port number

: Keyword user: string user Name

: Keyword passwd: string Password

: Keyword ssl: whether to enable ssl for bool. The default value is False.

: Keyword timeout: int timeout. The default value is 10 s.

: Param from_address: sender's email address

: Param to_address: Recipient's email address

: Param subject: Mail title

: Param body: email content

: Param files: attachment

: Raise: NetworkError/MailerException

"""

# Formatting mail content

Body = self. _ encode_utf8 (body)

# Mail type

Content_type = 'html' if body. startswith ('

Msg = MIMENonMultipart () if files else MIMEText (body, content_type, 'utf-8 ')

# Formatting mail data

Msg ['from'] = self. _ format_address (from_address)

Msg ['to'] = ','. join (self. _ format_list (to_address ))

Msg ['subobject'] = self. _ encode_utf8 (subject)

 

# Construct attachment data

If files:

Msg. attach (MIMEText (body, content_type, 'utf-8 '))

Cid = 0

For file_name, payload in files:

File_name = self. _ encode_utf8 (file_name)

Main_type, sub_type = self. _ get_file_type (file_name)

If hasattr (payload, 'read '):

Payload = payload. read ()

F_name = self. _ encode_header (file_name)

Mime = MIMEBase (main_type, sub_type, filename = f_name)

Mime. add_header ('content-disposition', 'attachment', filename = f_name)

Mime. add_header ('content-id', '<% s>' % cid)

Mime. add_header ('x-Attachment-id', '% s' % cid)

Mime. set_payload (payload)

Encoders. encode_base64 (mime)

Msg. attach (mime)

Cid + = 1

 

Host = smtp_server.get ('host ')

Port = smtp_server.get ('Port ')

User = smtp_server.get ('user ')

Passwd = smtp_server.get ('passwd ')

Ssl = smtp_server.get ('ssl ', False)

Time_out = smtp_server.get ('timeout', 10)

 

# Use the default port if no port is input

If port is None or port = 0:

If ssl:

Port = 465

Else:

Port = 25

 

Logging. debug ('send mail form % s to % s' % (msg ['from'], msg ['to'])

 

Try:

If ssl:

# Enable the ssl connection mode

Server = smtplib. SMTP_SSL ('% s: % d' % (host, port), timeout = time_out)

Else:

Server = smtplib. SMTP ('% s: % d' % (host, port), timeout = time_out)

# Enable debugging mode

# Server. set_debuglevel (1)

 

# Try to log on if the user name and password exist

If user and passwd:

Server. login (user, passwd)

 

# Send an email

Server. sendmail (from_address, to_address, msg. as_string ())

 

Logging. debug ('mail sent success .')

 

# Closing the stmp connection

Server. quit ()

 

Handle t socket. gaierror, e:

"The network cannot be connected """

Logging. exception (e)

Raise NetworkError (e)

 

Using t smtplib. SMTPServerDisconnected, e:

"Network connection exception """

Logging. exception (e)

Raise NetworkError (e)

 

Failed t smtplib. SMTPException, e:

"An error occurred while sending emails """

Logging. exception (e)

Raise MailerException (e)

 

Def _ format_address (self, s ):

"""

Format the email address

: Param s: string email address

: Return: string formatted email address

"""

Name, address = parseaddr (s)

Return formataddr (self. _ encode_header (name), self. _ encode_utf8 (address )))

 

Def _ encode_header (self, s ):

"""

Format MIME-compliant header data

: Param s: string data to be formatted

: Return: formatted data

"""

Return Header (s, 'utf-8'). encode ()

 

Def _ encode_utf8 (self, s ):

"""

Format to UTF-8 encoding

: Param s: string data to be formatted

: Return: string formatted data

"""

If isinstance (s, unicode ):

Return s. encode ('utf-8 ')

Else:

Return s

 

Def _ get_file_type (self, file_name ):

"""

Obtain the attachment type

: Param file_name: attachment file name

: Return: dict attachment MIME

"""

S = file_name.lower ()

Pos = s. rfind ('.')

If pos =-1:

Return 'application', 'octet-stream'

 

Ext = s [pos:]

Mime = mimetypes. types_map.get (ext, 'application/octet-stream ')

Pos = mime. find ('/')

If pos = (-1 ):

Return mime ,''

Return mime [: pos], mime [pos + 1:]

 

Def _ format_list (self, address ):

"""

Format the recipient address to list

: Param address: string/list recipient email

: Return: list recipient email list

"""

L = address

If isinstance (l, basestring ):

L = [l]

Return [self. _ format_address (s) for s in l]

 

 

Class MailerException (Exception ):

"Email sending exception """

Pass

 

 

Class NetworkError (MailerException ):

"Network exception """

Pass

 

# Test for @ qq.com

If _ name _ = '_ main __':

Import sys

 

Def prompt (prompt ):

"""

Receiving Terminal input data

"""

Sys. stdout. write (prompt + ":")

Return sys. stdin. readline (). strip ()

 

From_address = prompt ("From (Only @ qq.com )")

Passwd = prompt ("Password ")

To_address = prompt ("To"). split (',')

Subject = prompt ("Subject ")

Print "Enter message, end with ^ D :"

Msg =''

While 1:

Line = sys. stdin. readline ()

If not line:

Break

Msg = msg + line

Print "Message length is % d" % len (msg)

# QQ mail default settings

Smtp_server = {'host': 'smtp .qq.com ', 'Port': None, 'user': from_address, 'passwd': passwd, 'ssl': True}

Mailer = Mailer ()

 

Try:

Mailer. send_mail (smtp_server, from_address, to_address, subject, msg)

Failed t MailerException, e:

Print (e)

The above is all the content of this article. I hope you will like it.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.